summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/compiler/translator
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator')
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp445
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.h62
-rw-r--r--gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.cpp112
-rw-r--r--gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.h50
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BaseTypes.cpp64
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BaseTypes.h1782
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp161
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h80
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp284
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h40
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp173
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.cpp109
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/CallDAG.cpp316
-rw-r--r--gfx/angle/checkout/src/compiler/translator/CallDAG.h77
-rw-r--r--gfx/angle/checkout/src/compiler/translator/CodeGen.cpp96
-rw-r--r--gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp1288
-rw-r--r--gfx/angle/checkout/src/compiler/translator/CollectVariables.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Common.h256
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Compiler.cpp1746
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Compiler.h397
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ConstantUnion.cpp803
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ConstantUnion.h122
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Declarator.cpp33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Declarator.h49
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Diagnostics.cpp106
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Diagnostics.h67
-rw-r--r--gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp304
-rw-r--r--gfx/angle/checkout/src/compiler/translator/DirectiveHandler.h57
-rw-r--r--gfx/angle/checkout/src/compiler/translator/DriverUniformMetal.h33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.cpp125
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.h93
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.cpp118
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h44
-rw-r--r--gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp76
-rw-r--r--gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp179
-rw-r--r--gfx/angle/checkout/src/compiler/translator/FunctionLookup.h60
-rw-r--r--gfx/angle/checkout/src/compiler/translator/HashNames.cpp99
-rw-r--r--gfx/angle/checkout/src/compiler/translator/HashNames.h33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.cpp401
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.h96
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImmutableString.h143
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.cpp63
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h80
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImmutableString_ESSL_autogen.cpp345
-rw-r--r--gfx/angle/checkout/src/compiler/translator/InfoSink.cpp124
-rw-r--r--gfx/angle/checkout/src/compiler/translator/InfoSink.h152
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Initialize.cpp223
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Initialize.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/InitializeDll.cpp33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/InitializeDll.h15
-rw-r--r--gfx/angle/checkout/src/compiler/translator/InitializeGlobals.h13
-rw-r--r--gfx/angle/checkout/src/compiler/translator/IntermNode.cpp4226
-rw-r--r--gfx/angle/checkout/src/compiler/translator/IntermNode.h1046
-rw-r--r--gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp37
-rw-r--r--gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.h20
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Operator.cpp171
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Operator_autogen.h578
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputESSL.cpp55
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputESSL.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp122
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputGLSL.h31
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp1513
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h154
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp3700
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputHLSL.h289
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputTree.cpp723
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputTree.h22
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ParseContext.cpp7538
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ParseContext.h818
-rw-r--r--gfx/angle/checkout/src/compiler/translator/PoolAlloc.cpp40
-rw-r--r--gfx/angle/checkout/src/compiler/translator/PoolAlloc.h102
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Pragma.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/QualifierTypes.cpp1007
-rw-r--r--gfx/angle/checkout/src/compiler/translator/QualifierTypes.h214
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.cpp989
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.h155
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Severity.h22
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp1091
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp439
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.h94
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.cpp667
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.h86
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp625
-rw-r--r--gfx/angle/checkout/src/compiler/translator/StaticType.h296
-rw-r--r--gfx/angle/checkout/src/compiler/translator/StructureHLSL.cpp668
-rw-r--r--gfx/angle/checkout/src/compiler/translator/StructureHLSL.h102
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Symbol.cpp254
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Symbol.h402
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp559
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolTable.h363
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolTable_ESSL_autogen.cpp30071
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.h169
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h58
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.cpp1614
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.h77
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp219
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorESSL.h35
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp388
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp311
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.h56
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorMetal.h62
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorMetalDirect.h195
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorVulkan.h60
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Types.cpp984
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Types.h508
-rw-r--r--gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp1223
-rw-r--r--gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h148
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateAST.cpp1133
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateAST.h108
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.cpp100
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.h22
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.cpp200
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp157
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp452
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateLimitations.h26
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.h21
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp184
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateOutputs.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp315
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.cpp229
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp368
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/VariablePacker.cpp409
-rw-r--r--gfx/angle/checkout/src/compiler/translator/VariablePacker.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp156
-rw-r--r--gfx/angle/checkout/src/compiler/translator/VersionGLSL.h76
-rw-r--r--gfx/angle/checkout/src/compiler/translator/blocklayout.cpp666
-rw-r--r--gfx/angle/checkout/src/compiler/translator/blocklayout.h322
-rw-r--r--gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp167
-rw-r--r--gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.h68
-rw-r--r--gfx/angle/checkout/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp881
-rw-r--r--gfx/angle/checkout/src/compiler/translator/glslang.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/glslang_lex_autogen.cpp4326
-rw-r--r--gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.cpp4909
-rw-r--r--gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.h320
-rw-r--r--gfx/angle/checkout/src/compiler/translator/glslang_wrapper.h46
-rw-r--r--gfx/angle/checkout/src/compiler/translator/length_limits.h26
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp136
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp52
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.cpp335
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp196
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h52
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp180
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp142
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h35
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.cpp274
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h47
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp120
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.cpp101
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.h17
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp359
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.h60
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.cpp613
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h54
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.cpp127
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp127
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.h22
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp215
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp119
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.h33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp109
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h37
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp74
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp597
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.h41
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.cpp209
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h42
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp47
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.h21
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp371
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.cpp348
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.cpp328
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.cpp984
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.cpp141
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.cpp861
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.cpp673
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp168
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.h34
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp223
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp199
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.cpp115
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h39
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp499
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp173
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.cpp60
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h31
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.cpp147
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.cpp1595
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h37
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.cpp97
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.h31
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.cpp74
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.cpp61
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.cpp82
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h23
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.cpp76
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.h23
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.cpp233
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.cpp110
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.cpp152
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.h34
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.cpp385
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.cpp270
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.cpp183
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h42
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.cpp123
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.cpp420
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h37
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.cpp117
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h23
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.cpp83
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.cpp89
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.cpp138
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.cpp200
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.cpp126
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp54
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.h39
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.cpp119
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.h34
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp97
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h40
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.cpp108
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h44
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/AsNode.h212
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn.h18
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_ESSL_autogen.h4177
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_complete_autogen.h5008
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.cpp435
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.h110
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.cpp32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.h21
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.cpp54
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.cpp703
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp53
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.h23
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp213
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.h81
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.cpp436
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.h128
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.cpp1046
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.h328
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.cpp708
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.h379
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/NodeSearch.h56
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/NodeType.h155
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp175
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.h33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.cpp591
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.h43
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.cpp142
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.h26
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp145
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.h48
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.cpp198
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.cpp35
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp129
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.cpp122
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.h55
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/Visit.h22
-rw-r--r--gfx/angle/checkout/src/compiler/translator/util.cpp1023
-rw-r--r--gfx/angle/checkout/src/compiler/translator/util.h108
308 files changed, 126962 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp
new file mode 100644
index 0000000000..69b50c5d7d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp
@@ -0,0 +1,445 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Analysis of the AST needed for HLSL generation
+
+#include "compiler/translator/ASTMetadataHLSL.h"
+
+#include "compiler/translator/CallDAG.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Class used to traverse the AST of a function definition, checking if the
+// function uses a gradient, and writing the set of control flow using gradients.
+// It assumes that the analysis has already been made for the function's
+// callees.
+class PullGradient : public TIntermTraverser
+{
+ public:
+ PullGradient(MetadataList *metadataList, size_t index, const CallDAG &dag)
+ : TIntermTraverser(true, false, true),
+ mMetadataList(metadataList),
+ mMetadata(&(*metadataList)[index]),
+ mIndex(index),
+ mDag(dag)
+ {
+ ASSERT(index < metadataList->size());
+
+ // ESSL 100 builtin gradient functions
+ mGradientBuiltinFunctions.insert(ImmutableString("texture2D"));
+ mGradientBuiltinFunctions.insert(ImmutableString("texture2DProj"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureCube"));
+
+ // ESSL 300 builtin gradient functions
+ mGradientBuiltinFunctions.insert(ImmutableString("dFdx"));
+ mGradientBuiltinFunctions.insert(ImmutableString("dFdy"));
+ mGradientBuiltinFunctions.insert(ImmutableString("fwidth"));
+ mGradientBuiltinFunctions.insert(ImmutableString("texture"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureProj"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureOffset"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureProjOffset"));
+
+ // ESSL 310 doesn't add builtin gradient functions
+ }
+
+ void traverse(TIntermFunctionDefinition *node)
+ {
+ node->traverse(this);
+ ASSERT(mParents.empty());
+ }
+
+ // Called when a gradient operation or a call to a function using a gradient is found.
+ void onGradient()
+ {
+ mMetadata->mUsesGradient = true;
+ // Mark the latest control flow as using a gradient.
+ if (!mParents.empty())
+ {
+ mMetadata->mControlFlowsContainingGradient.insert(mParents.back());
+ }
+ }
+
+ void visitControlFlow(Visit visit, TIntermNode *node)
+ {
+ if (visit == PreVisit)
+ {
+ mParents.push_back(node);
+ }
+ else if (visit == PostVisit)
+ {
+ ASSERT(mParents.back() == node);
+ mParents.pop_back();
+ // A control flow's using a gradient means its parents are too.
+ if (mMetadata->mControlFlowsContainingGradient.count(node) > 0 && !mParents.empty())
+ {
+ mMetadata->mControlFlowsContainingGradient.insert(mParents.back());
+ }
+ }
+ }
+
+ bool visitLoop(Visit visit, TIntermLoop *loop) override
+ {
+ visitControlFlow(visit, loop);
+ return true;
+ }
+
+ bool visitIfElse(Visit visit, TIntermIfElse *ifElse) override
+ {
+ visitControlFlow(visit, ifElse);
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (visit == PreVisit)
+ {
+ if (node->getOp() == EOpCallFunctionInAST)
+ {
+ size_t calleeIndex = mDag.findIndex(node->getFunction()->uniqueId());
+ ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
+
+ if ((*mMetadataList)[calleeIndex].mUsesGradient)
+ {
+ onGradient();
+ }
+ }
+ else if (BuiltInGroup::IsBuiltIn(node->getOp()) && !BuiltInGroup::IsMath(node->getOp()))
+ {
+ if (mGradientBuiltinFunctions.find(node->getFunction()->name()) !=
+ mGradientBuiltinFunctions.end())
+ {
+ onGradient();
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private:
+ MetadataList *mMetadataList;
+ ASTMetadataHLSL *mMetadata;
+ size_t mIndex;
+ const CallDAG &mDag;
+
+ // Contains a stack of the control flow nodes that are parents of the node being
+ // currently visited. It is used to mark control flows using a gradient.
+ std::vector<TIntermNode *> mParents;
+
+ // A list of builtin functions that use gradients
+ std::set<ImmutableString> mGradientBuiltinFunctions;
+};
+
+// Traverses the AST of a function definition to compute the the discontinuous loops
+// and the if statements containing gradient loops. It assumes that the gradient loops
+// (loops that contain a gradient) have already been computed and that it has already
+// traversed the current function's callees.
+class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
+{
+ public:
+ PullComputeDiscontinuousAndGradientLoops(MetadataList *metadataList,
+ size_t index,
+ const CallDAG &dag)
+ : TIntermTraverser(true, false, true),
+ mMetadataList(metadataList),
+ mMetadata(&(*metadataList)[index]),
+ mIndex(index),
+ mDag(dag)
+ {}
+
+ void traverse(TIntermFunctionDefinition *node)
+ {
+ node->traverse(this);
+ ASSERT(mLoopsAndSwitches.empty());
+ ASSERT(mIfs.empty());
+ }
+
+ // Called when traversing a gradient loop or a call to a function with a
+ // gradient loop in its call graph.
+ void onGradientLoop()
+ {
+ mMetadata->mHasGradientLoopInCallGraph = true;
+ // Mark the latest if as using a discontinuous loop.
+ if (!mIfs.empty())
+ {
+ mMetadata->mIfsContainingGradientLoop.insert(mIfs.back());
+ }
+ }
+
+ bool visitLoop(Visit visit, TIntermLoop *loop) override
+ {
+ if (visit == PreVisit)
+ {
+ mLoopsAndSwitches.push_back(loop);
+
+ if (mMetadata->hasGradientInCallGraph(loop))
+ {
+ onGradientLoop();
+ }
+ }
+ else if (visit == PostVisit)
+ {
+ ASSERT(mLoopsAndSwitches.back() == loop);
+ mLoopsAndSwitches.pop_back();
+ }
+
+ return true;
+ }
+
+ bool visitIfElse(Visit visit, TIntermIfElse *node) override
+ {
+ if (visit == PreVisit)
+ {
+ mIfs.push_back(node);
+ }
+ else if (visit == PostVisit)
+ {
+ ASSERT(mIfs.back() == node);
+ mIfs.pop_back();
+ // An if using a discontinuous loop means its parents ifs are also discontinuous.
+ if (mMetadata->mIfsContainingGradientLoop.count(node) > 0 && !mIfs.empty())
+ {
+ mMetadata->mIfsContainingGradientLoop.insert(mIfs.back());
+ }
+ }
+
+ return true;
+ }
+
+ bool visitBranch(Visit visit, TIntermBranch *node) override
+ {
+ if (visit == PreVisit)
+ {
+ switch (node->getFlowOp())
+ {
+ case EOpBreak:
+ {
+ ASSERT(!mLoopsAndSwitches.empty());
+ TIntermLoop *loop = mLoopsAndSwitches.back()->getAsLoopNode();
+ if (loop != nullptr)
+ {
+ mMetadata->mDiscontinuousLoops.insert(loop);
+ }
+ }
+ break;
+ case EOpContinue:
+ {
+ ASSERT(!mLoopsAndSwitches.empty());
+ TIntermLoop *loop = nullptr;
+ size_t i = mLoopsAndSwitches.size();
+ while (loop == nullptr && i > 0)
+ {
+ --i;
+ loop = mLoopsAndSwitches.at(i)->getAsLoopNode();
+ }
+ ASSERT(loop != nullptr);
+ mMetadata->mDiscontinuousLoops.insert(loop);
+ }
+ break;
+ case EOpKill:
+ case EOpReturn:
+ // A return or discard jumps out of all the enclosing loops
+ if (!mLoopsAndSwitches.empty())
+ {
+ for (TIntermNode *intermNode : mLoopsAndSwitches)
+ {
+ TIntermLoop *loop = intermNode->getAsLoopNode();
+ if (loop)
+ {
+ mMetadata->mDiscontinuousLoops.insert(loop);
+ }
+ }
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (visit == PreVisit && node->getOp() == EOpCallFunctionInAST)
+ {
+ size_t calleeIndex = mDag.findIndex(node->getFunction()->uniqueId());
+ ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
+
+ if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph)
+ {
+ onGradientLoop();
+ }
+ }
+
+ return true;
+ }
+
+ bool visitSwitch(Visit visit, TIntermSwitch *node) override
+ {
+ if (visit == PreVisit)
+ {
+ mLoopsAndSwitches.push_back(node);
+ }
+ else if (visit == PostVisit)
+ {
+ ASSERT(mLoopsAndSwitches.back() == node);
+ mLoopsAndSwitches.pop_back();
+ }
+ return true;
+ }
+
+ private:
+ MetadataList *mMetadataList;
+ ASTMetadataHLSL *mMetadata;
+ size_t mIndex;
+ const CallDAG &mDag;
+
+ std::vector<TIntermNode *> mLoopsAndSwitches;
+ std::vector<TIntermIfElse *> mIfs;
+};
+
+// Tags all the functions called in a discontinuous loop
+class PushDiscontinuousLoops : public TIntermTraverser
+{
+ public:
+ PushDiscontinuousLoops(MetadataList *metadataList, size_t index, const CallDAG &dag)
+ : TIntermTraverser(true, true, true),
+ mMetadataList(metadataList),
+ mMetadata(&(*metadataList)[index]),
+ mIndex(index),
+ mDag(dag),
+ mNestedDiscont(mMetadata->mCalledInDiscontinuousLoop ? 1 : 0)
+ {}
+
+ void traverse(TIntermFunctionDefinition *node)
+ {
+ node->traverse(this);
+ ASSERT(mNestedDiscont == (mMetadata->mCalledInDiscontinuousLoop ? 1 : 0));
+ }
+
+ bool visitLoop(Visit visit, TIntermLoop *loop) override
+ {
+ bool isDiscontinuous = mMetadata->mDiscontinuousLoops.count(loop) > 0;
+
+ if (visit == PreVisit && isDiscontinuous)
+ {
+ mNestedDiscont++;
+ }
+ else if (visit == PostVisit && isDiscontinuous)
+ {
+ mNestedDiscont--;
+ }
+
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ switch (node->getOp())
+ {
+ case EOpCallFunctionInAST:
+ if (visit == PreVisit && mNestedDiscont > 0)
+ {
+ size_t calleeIndex = mDag.findIndex(node->getFunction()->uniqueId());
+ ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
+
+ (*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true;
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ private:
+ MetadataList *mMetadataList;
+ ASTMetadataHLSL *mMetadata;
+ size_t mIndex;
+ const CallDAG &mDag;
+
+ int mNestedDiscont;
+};
+} // namespace
+
+bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node)
+{
+ return mControlFlowsContainingGradient.count(node) > 0;
+}
+
+bool ASTMetadataHLSL::hasGradientLoop(TIntermIfElse *node)
+{
+ return mIfsContainingGradientLoop.count(node) > 0;
+}
+
+MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag)
+{
+ MetadataList metadataList(callDag.size());
+
+ // Compute all the information related to when gradient operations are used.
+ // We want to know for each function and control flow operation if they have
+ // a gradient operation in their call graph (shortened to "using a gradient"
+ // in the rest of the file).
+ //
+ // This computation is logically split in three steps:
+ // 1 - For each function compute if it uses a gradient in its body, ignoring
+ // calls to other user-defined functions.
+ // 2 - For each function determine if it uses a gradient in its call graph,
+ // using the result of step 1 and the CallDAG to know its callees.
+ // 3 - For each control flow statement of each function, check if it uses a
+ // gradient in the function's body, or if it calls a user-defined function that
+ // uses a gradient.
+ //
+ // We take advantage of the call graph being a DAG and instead compute 1, 2 and 3
+ // for leaves first, then going down the tree. This is correct because 1 doesn't
+ // depend on other functions, and 2 and 3 depend only on callees.
+ for (size_t i = 0; i < callDag.size(); i++)
+ {
+ PullGradient pull(&metadataList, i, callDag);
+ pull.traverse(callDag.getRecordFromIndex(i).node);
+ }
+
+ // Compute which loops are discontinuous and which function are called in
+ // these loops. The same way computing gradient usage is a "pull" process,
+ // computing "bing used in a discont. loop" is a push process. However we also
+ // need to know what ifs have a discontinuous loop inside so we do the same type
+ // of callgraph analysis as for the gradient.
+
+ // First compute which loops are discontinuous (no specific order) and pull
+ // the ifs and functions using a gradient loop.
+ for (size_t i = 0; i < callDag.size(); i++)
+ {
+ PullComputeDiscontinuousAndGradientLoops pull(&metadataList, i, callDag);
+ pull.traverse(callDag.getRecordFromIndex(i).node);
+ }
+
+ // Then push the information to callees, either from the a local discontinuous
+ // loop or from the caller being called in a discontinuous loop already
+ for (size_t i = callDag.size(); i-- > 0;)
+ {
+ PushDiscontinuousLoops push(&metadataList, i, callDag);
+ push.traverse(callDag.getRecordFromIndex(i).node);
+ }
+
+ // We create "Lod0" version of functions with the gradient operations replaced
+ // by non-gradient operations so that the D3D compiler is happier with discont
+ // loops.
+ for (auto &metadata : metadataList)
+ {
+ metadata.mNeedsLod0 = metadata.mCalledInDiscontinuousLoop && metadata.mUsesGradient;
+ }
+
+ return metadataList;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.h b/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.h
new file mode 100644
index 0000000000..8278f9fafe
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.h
@@ -0,0 +1,62 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Defines analyses of the AST needed for HLSL generation
+
+#ifndef COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
+#define COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
+
+#include <set>
+#include <vector>
+
+namespace sh
+{
+
+class CallDAG;
+class TIntermNode;
+class TIntermIfElse;
+class TIntermLoop;
+
+struct ASTMetadataHLSL
+{
+ ASTMetadataHLSL()
+ : mUsesGradient(false),
+ mCalledInDiscontinuousLoop(false),
+ mHasGradientLoopInCallGraph(false),
+ mNeedsLod0(false)
+ {}
+
+ // Here "something uses a gradient" means here that it either contains a
+ // gradient operation, or a call to a function that uses a gradient.
+ bool hasGradientInCallGraph(TIntermLoop *node);
+ bool hasGradientLoop(TIntermIfElse *node);
+
+ // Does the function use a gradient.
+ bool mUsesGradient;
+
+ // Even if usesGradient is true, some control flow might not use a gradient
+ // so we store the set of all gradient-using control flows.
+ std::set<TIntermNode *> mControlFlowsContainingGradient;
+
+ // Remember information about the discontinuous loops and which functions
+ // are called in such loops.
+ bool mCalledInDiscontinuousLoop;
+ bool mHasGradientLoopInCallGraph;
+ std::set<TIntermLoop *> mDiscontinuousLoops;
+ std::set<TIntermIfElse *> mIfsContainingGradientLoop;
+
+ // Will we need to generate a Lod0 version of the function.
+ bool mNeedsLod0;
+};
+
+typedef std::vector<ASTMetadataHLSL> MetadataList;
+
+// Return the AST analysis result, in the order defined by the call DAG
+MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.cpp
new file mode 100644
index 0000000000..b900bc4d81
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.cpp
@@ -0,0 +1,112 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// AtomicCounterFunctionHLSL: Class for writing implementation of atomic counter functions into HLSL
+// output.
+//
+
+#include "compiler/translator/AtomicCounterFunctionHLSL.h"
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr ImmutableString kAtomicCounter("atomicCounter");
+constexpr ImmutableString kAtomicCounterIncrement("atomicCounterIncrement");
+constexpr ImmutableString kAtomicCounterDecrement("atomicCounterDecrement");
+constexpr ImmutableString kAtomicCounterBaseName("_acbase_");
+} // namespace
+
+AtomicCounterFunctionHLSL::AtomicCounterFunctionHLSL(bool forceResolution)
+ : mForceResolution(forceResolution)
+{}
+
+ImmutableString AtomicCounterFunctionHLSL::useAtomicCounterFunction(const ImmutableString &name)
+{
+ // The largest string that will be create created is "_acbase_increment" or "_acbase_decrement"
+ ImmutableStringBuilder hlslFunctionNameSB(kAtomicCounterBaseName.length() +
+ strlen("increment"));
+ hlslFunctionNameSB << kAtomicCounterBaseName;
+
+ AtomicCounterFunction atomicMethod;
+ if (kAtomicCounter == name)
+ {
+ atomicMethod = AtomicCounterFunction::LOAD;
+ hlslFunctionNameSB << "load";
+ }
+ else if (kAtomicCounterIncrement == name)
+ {
+ atomicMethod = AtomicCounterFunction::INCREMENT;
+ hlslFunctionNameSB << "increment";
+ }
+ else if (kAtomicCounterDecrement == name)
+ {
+ atomicMethod = AtomicCounterFunction::DECREMENT;
+ hlslFunctionNameSB << "decrement";
+ }
+ else
+ {
+ atomicMethod = AtomicCounterFunction::INVALID;
+ UNREACHABLE();
+ }
+
+ ImmutableString hlslFunctionName(hlslFunctionNameSB);
+ mAtomicCounterFunctions[hlslFunctionName] = atomicMethod;
+
+ return hlslFunctionName;
+}
+
+void AtomicCounterFunctionHLSL::atomicCounterFunctionHeader(TInfoSinkBase &out)
+{
+ for (auto &atomicFunction : mAtomicCounterFunctions)
+ {
+ out << "uint " << atomicFunction.first
+ << "(in RWByteAddressBuffer counter, int address)\n"
+ "{\n"
+ " uint ret;\n";
+
+ switch (atomicFunction.second)
+ {
+ case AtomicCounterFunction::INCREMENT:
+ out << " counter.InterlockedAdd(address, 1u, ret);\n";
+ break;
+ case AtomicCounterFunction::DECREMENT:
+ out << " counter.InterlockedAdd(address, 0u - 1u, ret);\n"
+ " ret -= 1u;\n"; // atomicCounterDecrement is a post-decrement op
+ break;
+ case AtomicCounterFunction::LOAD:
+ out << " ret = counter.Load(address);\n";
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (mForceResolution && atomicFunction.second != AtomicCounterFunction::LOAD)
+ {
+ out << " if (ret == 0) {\n"
+ " ret = 0 - ret;\n"
+ " }\n";
+ }
+
+ out << " return ret;\n"
+ "}\n\n";
+ }
+}
+
+ImmutableString getAtomicCounterNameForBinding(int binding)
+{
+ std::stringstream counterName = sh::InitializeStream<std::stringstream>();
+ counterName << kAtomicCounterBaseName << binding;
+ return ImmutableString(counterName.str());
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.h b/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.h
new file mode 100644
index 0000000000..669e567476
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.h
@@ -0,0 +1,50 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// AtomicCounterFunctionHLSL: Class for writing implementation of atomic counter functions into HLSL
+// output.
+//
+
+#ifndef COMPILER_TRANSLATOR_ATOMICCOUNTERFUNCTIONHLSL_H_
+#define COMPILER_TRANSLATOR_ATOMICCOUNTERFUNCTIONHLSL_H_
+
+#include <map>
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/ImmutableString.h"
+
+namespace sh
+{
+
+class TInfoSinkBase;
+struct TLayoutQualifier;
+
+class AtomicCounterFunctionHLSL final : angle::NonCopyable
+{
+ public:
+ AtomicCounterFunctionHLSL(bool forceResolution);
+
+ ImmutableString useAtomicCounterFunction(const ImmutableString &name);
+
+ void atomicCounterFunctionHeader(TInfoSinkBase &out);
+
+ private:
+ enum class AtomicCounterFunction
+ {
+ LOAD,
+ INCREMENT,
+ DECREMENT,
+ INVALID
+ };
+
+ std::map<ImmutableString, AtomicCounterFunction> mAtomicCounterFunctions;
+ bool mForceResolution;
+};
+
+ImmutableString getAtomicCounterNameForBinding(int binding);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_ATOMICCOUNTERFUNCTIONHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/BaseTypes.cpp b/gfx/angle/checkout/src/compiler/translator/BaseTypes.cpp
new file mode 100644
index 0000000000..15a3ebebc8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BaseTypes.cpp
@@ -0,0 +1,64 @@
+//
+// Copyright 2022 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "BaseTypes.h"
+
+#include "common/PackedEnums.h"
+
+namespace sh
+{
+namespace
+{
+constexpr gl::BlendEquationBitSet kAdvancedBlendBits{
+ gl::BlendEquationType::Multiply, gl::BlendEquationType::Screen,
+ gl::BlendEquationType::Overlay, gl::BlendEquationType::Darken,
+ gl::BlendEquationType::Lighten, gl::BlendEquationType::Colordodge,
+ gl::BlendEquationType::Colorburn, gl::BlendEquationType::Hardlight,
+ gl::BlendEquationType::Softlight, gl::BlendEquationType::Difference,
+ gl::BlendEquationType::Exclusion, gl::BlendEquationType::HslHue,
+ gl::BlendEquationType::HslSaturation, gl::BlendEquationType::HslColor,
+ gl::BlendEquationType::HslLuminosity,
+};
+
+constexpr gl::BlendEquationBitSet kAdvancedBlendHslBits{
+ gl::BlendEquationType::HslHue,
+ gl::BlendEquationType::HslSaturation,
+ gl::BlendEquationType::HslColor,
+ gl::BlendEquationType::HslLuminosity,
+};
+
+bool IsValidAdvancedBlendBitSet(uint32_t enabledEquations)
+{
+ return (gl::BlendEquationBitSet(enabledEquations) & ~kAdvancedBlendBits).none();
+}
+} // anonymous namespace
+
+bool AdvancedBlendEquations::any() const
+{
+ ASSERT(IsValidAdvancedBlendBitSet(mEnabledBlendEquations));
+ return mEnabledBlendEquations != 0;
+}
+
+bool AdvancedBlendEquations::anyHsl() const
+{
+ ASSERT(IsValidAdvancedBlendBitSet(mEnabledBlendEquations));
+ return (gl::BlendEquationBitSet(mEnabledBlendEquations) & kAdvancedBlendHslBits).any();
+}
+
+void AdvancedBlendEquations::setAll()
+{
+ ASSERT(IsValidAdvancedBlendBitSet(mEnabledBlendEquations));
+ mEnabledBlendEquations = kAdvancedBlendBits.bits();
+}
+
+void AdvancedBlendEquations::set(uint32_t blendEquation)
+{
+ gl::BlendEquationType eq = static_cast<gl::BlendEquationType>(blendEquation);
+ mEnabledBlendEquations = gl::BlendEquationBitSet(mEnabledBlendEquations).set(eq).bits();
+ ASSERT(IsValidAdvancedBlendBitSet(mEnabledBlendEquations));
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/BaseTypes.h b/gfx/angle/checkout/src/compiler/translator/BaseTypes.h
new file mode 100644
index 0000000000..7e569f4e9d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BaseTypes.h
@@ -0,0 +1,1782 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_BASETYPES_H_
+#define COMPILER_TRANSLATOR_BASETYPES_H_
+
+#include <algorithm>
+#include <array>
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/debug.h"
+#include "compiler/translator/ImmutableString.h"
+
+namespace sh
+{
+
+//
+// Precision qualifiers
+//
+enum TPrecision
+{
+ // These need to be kept sorted
+ EbpUndefined,
+ EbpLow,
+ EbpMedium,
+ EbpHigh,
+
+ // end of list
+ EbpLast
+};
+
+inline const char *getPrecisionString(TPrecision p)
+{
+ switch (p)
+ {
+ case EbpHigh:
+ return "highp";
+ case EbpMedium:
+ return "mediump";
+ case EbpLow:
+ return "lowp";
+ default:
+ return "mediump"; // Safest fallback
+ }
+}
+
+//
+// Basic type. Arrays, vectors, etc., are orthogonal to this.
+//
+enum TBasicType
+{
+ EbtVoid,
+ EbtFloat,
+ EbtDouble,
+ EbtInt,
+ EbtUInt,
+ EbtBool,
+
+ EbtAtomicCounter,
+ EbtYuvCscStandardEXT, // Only valid if EXT_YUV_target exists.
+
+ EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
+ EbtSampler2D = EbtGuardSamplerBegin,
+ EbtSampler3D,
+ EbtSamplerCube,
+ EbtSampler2DArray,
+ EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists.
+ EbtSamplerExternal2DY2YEXT, // Only valid if GL_EXT_YUV_target exists.
+ EbtSampler2DRect, // Only valid if GL_ARB_texture_rectangle exists.
+ EbtSampler2DMS,
+ EbtSampler2DMSArray,
+ EbtISampler2D,
+ EbtISampler3D,
+ EbtISamplerCube,
+ EbtISampler2DArray,
+ EbtISampler2DMS,
+ EbtISampler2DMSArray,
+ EbtUSampler2D,
+ EbtUSampler3D,
+ EbtUSamplerCube,
+ EbtUSampler2DArray,
+ EbtUSampler2DMS,
+ EbtUSampler2DMSArray,
+ EbtSampler2DShadow,
+ EbtSamplerCubeShadow,
+ EbtSampler2DArrayShadow,
+ EbtSampler1D, // Desktop GLSL sampler types
+ EbtSampler1DArray,
+ EbtSampler1DArrayShadow,
+ EbtSamplerBuffer,
+ EbtSamplerCubeArray,
+ EbtSamplerCubeArrayShadow,
+ EbtSampler1DShadow,
+ EbtSampler2DRectShadow,
+ EbtISampler1D,
+ EbtISampler1DArray,
+ EbtISampler2DRect,
+ EbtISamplerBuffer,
+ EbtISamplerCubeArray,
+ EbtUSampler1D,
+ EbtUSampler1DArray,
+ EbtUSampler2DRect,
+ EbtUSamplerBuffer,
+ EbtUSamplerCubeArray,
+ EbtSamplerVideoWEBGL,
+ EbtGuardSamplerEnd = EbtSamplerVideoWEBGL, // non type: see implementation of IsSampler()
+
+ // images
+ EbtGuardImageBegin,
+ EbtImage2D = EbtGuardImageBegin,
+ EbtImage3D,
+ EbtImage2DArray,
+ EbtImageCube,
+ EbtImage1D,
+ EbtImage1DArray,
+ EbtImage2DMS,
+ EbtImage2DMSArray,
+ EbtImageCubeArray,
+ EbtImageRect,
+ EbtImageBuffer,
+ EbtIImage2D,
+ EbtIImage3D,
+ EbtIImage2DArray,
+ EbtIImageCube,
+ EbtIImage1D,
+ EbtIImage1DArray,
+ EbtIImage2DMS,
+ EbtIImage2DMSArray,
+ EbtIImageCubeArray,
+ EbtIImageRect,
+ EbtIImageBuffer,
+ EbtGuardUIntImageBegin,
+ EbtUImage2D = EbtGuardUIntImageBegin,
+ EbtUImage3D,
+ EbtUImage2DArray,
+ EbtUImageCube,
+ EbtUImage1D,
+ EbtUImage1DArray,
+ EbtUImage2DMS,
+ EbtUImage2DMSArray,
+ EbtUImageCubeArray,
+ EbtUImageRect,
+ EbtUImageBuffer,
+ EbtGuardUIntImageEnd = EbtUImageBuffer,
+ EbtGuardImageEnd = EbtGuardUIntImageEnd,
+
+ // ANGLE_shader_pixel_local_storage
+ EbtGuardPixelLocalBegin,
+ EbtPixelLocalANGLE = EbtGuardPixelLocalBegin,
+ EbtIPixelLocalANGLE,
+ EbtUPixelLocalANGLE,
+ EbtGuardPixelLocalEnd = EbtUPixelLocalANGLE,
+
+ // Subpass Input
+ EbtGuardSubpassInputBegin,
+ EbtSubpassInput = EbtGuardSubpassInputBegin,
+ EbtISubpassInput,
+ EbtUSubpassInput,
+ EbtSubpassInputMS,
+ EbtISubpassInputMS,
+ EbtUSubpassInputMS,
+ EbtGuardSubpassInputEnd = EbtUSubpassInputMS,
+
+ EbtLastSimpleType = EbtGuardSubpassInputEnd,
+
+ EbtStruct,
+ EbtInterfaceBlock,
+
+ // end of list
+ EbtLast = EbtInterfaceBlock
+};
+
+class TBasicMangledName
+{
+ public:
+ constexpr TBasicMangledName(TBasicType t) : mName{'\0', '\0'}
+ {
+ if (t > EbtLastSimpleType)
+ {
+ mName[0] = '{';
+ mName[1] = '\0';
+ }
+ else if (t < 26)
+ {
+ mName[0] = '0';
+ mName[1] = static_cast<char>('A' + t);
+ }
+ else if (t < 52)
+ {
+ mName[0] = '0';
+ mName[1] = static_cast<char>('a' - 26 + t);
+ }
+ else if (t < 78)
+ {
+ mName[0] = '1';
+ mName[1] = static_cast<char>('A' - 52 + t);
+ }
+ else if (t < 104)
+ {
+ mName[0] = '1';
+ mName[1] = static_cast<char>('a' - 78 + t);
+ }
+ }
+
+ constexpr char *getName() { return mName; }
+
+ static constexpr int mangledNameSize = 2;
+
+ private:
+ char mName[mangledNameSize];
+};
+
+const char *getBasicString(TBasicType t);
+
+inline bool IsSampler(TBasicType type)
+{
+ return type >= EbtGuardSamplerBegin && type <= EbtGuardSamplerEnd;
+}
+
+inline bool IsImage(TBasicType type)
+{
+ return type >= EbtGuardImageBegin && type <= EbtGuardImageEnd;
+}
+
+inline bool IsUIntImage(TBasicType type)
+{
+ return type >= EbtGuardUIntImageBegin && type <= EbtGuardUIntImageEnd;
+}
+
+inline bool IsAtomicCounter(TBasicType type)
+{
+ return type == EbtAtomicCounter;
+}
+
+inline bool IsPixelLocal(TBasicType type)
+{
+ return type >= EbtGuardPixelLocalBegin && type <= EbtGuardPixelLocalEnd;
+}
+
+inline bool IsSubpassInputType(TBasicType type)
+{
+ return type >= EbtGuardSubpassInputBegin && type <= EbtGuardSubpassInputEnd;
+}
+
+inline bool IsOpaqueType(TBasicType type)
+{
+ return IsSampler(type) || IsImage(type) || IsAtomicCounter(type) || IsPixelLocal(type) ||
+ IsSubpassInputType(type);
+}
+
+inline bool IsIntegerSampler(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtISampler2D:
+ case EbtISampler3D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2D:
+ case EbtUSampler3D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ return true;
+ case EbtSampler2D:
+ case EbtSampler3D:
+ case EbtSamplerCube:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DRect:
+ case EbtSampler2DArray:
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtSampler1D:
+ case EbtSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler1DShadow:
+ case EbtSampler2DRectShadow:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsIntegerSamplerUnsigned(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtISampler2D:
+ case EbtISampler3D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ return false;
+ case EbtUSampler2D:
+ case EbtUSampler3D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ return true;
+ default:
+ ASSERT(!IsIntegerSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSampler2DMS(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler2DMS:
+ case EbtISampler2DMS:
+ case EbtUSampler2DMS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsSampler2DMSArray(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler2DMSArray:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2DMSArray:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsSamplerMS(TBasicType type)
+{
+ return IsSampler2DMS(type) || IsSampler2DMSArray(type);
+}
+
+inline bool IsImageMS(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImage2DMS:
+ case EbtImage2DMSArray:
+ case EbtIImage2DMS:
+ case EbtIImage2DMSArray:
+ case EbtUImage2DMS:
+ case EbtUImage2DMSArray:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsFloatImage(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImage1D:
+ case EbtImage2D:
+ case EbtImage3D:
+ case EbtImage1DArray:
+ case EbtImage2DArray:
+ case EbtImageCube:
+ case EbtImage2DMS:
+ case EbtImage2DMSArray:
+ case EbtImageCubeArray:
+ case EbtImageRect:
+ case EbtImageBuffer:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+inline bool IsIntegerImage(TBasicType type)
+{
+
+ switch (type)
+ {
+ case EbtIImage1D:
+ case EbtIImage2D:
+ case EbtIImage3D:
+ case EbtIImage1DArray:
+ case EbtIImage2DArray:
+ case EbtIImageCube:
+ case EbtIImage2DMS:
+ case EbtIImage2DMSArray:
+ case EbtIImageCubeArray:
+ case EbtIImageRect:
+ case EbtIImageBuffer:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+inline bool IsUnsignedImage(TBasicType type)
+{
+
+ switch (type)
+ {
+ case EbtUImage1D:
+ case EbtUImage2D:
+ case EbtUImage3D:
+ case EbtUImage1DArray:
+ case EbtUImage2DArray:
+ case EbtUImageCube:
+ case EbtUImage2DMS:
+ case EbtUImage2DMSArray:
+ case EbtUImageCubeArray:
+ case EbtUImageRect:
+ case EbtUImageBuffer:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+// Samplers are divided into 4 disjoint categories: 2D, cube, 3D, and array.
+// Array samplers are not 2D samplers.
+inline bool IsSampler2D(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DRect:
+ case EbtISampler2DRect:
+ case EbtUSampler2DRect:
+ case EbtSampler2DRectShadow:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DShadow:
+ case EbtSampler2DMS:
+ case EbtISampler2DMS:
+ case EbtUSampler2DMS:
+ case EbtSamplerVideoWEBGL:
+ return true;
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ case EbtSampler2DMSArray:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DArrayShadow:
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCube:
+ case EbtSamplerCubeShadow:
+ case EbtSampler1D:
+ case EbtSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler1DShadow:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSamplerCube(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSamplerCube:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCubeShadow:
+ return true;
+ case EbtSampler2D:
+ case EbtSampler3D:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DRect:
+ case EbtSampler2DArray:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtISampler2D:
+ case EbtISampler3D:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2D:
+ case EbtUSampler3D:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSampler1D:
+ case EbtSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler1DShadow:
+ case EbtSampler2DRectShadow:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSampler3D(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ return true;
+ case EbtSampler2D:
+ case EbtSamplerCube:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DRect:
+ case EbtSampler2DArray:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtISampler2D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSampler1D:
+ case EbtSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler1DShadow:
+ case EbtSampler2DRectShadow:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSamplerArray(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler1DArray:
+ case EbtISampler1DArray:
+ case EbtUSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ case EbtSampler2DMSArray:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DArrayShadow:
+ case EbtSamplerCubeArray:
+ case EbtISamplerCubeArray:
+ case EbtUSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ return true;
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DRect:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCube:
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler2DMS:
+ case EbtISampler2DMS:
+ case EbtUSampler2DMS:
+ case EbtSampler1D:
+ case EbtSamplerBuffer:
+ case EbtSampler1DShadow:
+ case EbtSampler2DRectShadow:
+ case EbtISampler1D:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtUSampler1D:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSampler1D(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler1D:
+ case EbtISampler1D:
+ case EbtUSampler1D:
+ case EbtSampler1DShadow:
+ return true;
+ case EbtSampler2D:
+ case EbtSamplerCube:
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DRect:
+ case EbtSampler2DArray:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtISampler2D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler2DRectShadow:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSamplerBuffer(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSamplerBuffer:
+ case EbtISamplerBuffer:
+ case EbtUSamplerBuffer:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsShadowSampler(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler1DShadow:
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler1DArrayShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler2DRectShadow:
+ return true;
+ case EbtISampler2D:
+ case EbtISampler3D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2D:
+ case EbtUSampler3D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2D:
+ case EbtSampler3D:
+ case EbtSamplerCube:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DRect:
+ case EbtSampler2DArray:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtSampler1D:
+ case EbtSampler1DArray:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsImage2D(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ case EbtImage2DMS:
+ case EbtIImage2DMS:
+ case EbtUImage2DMS:
+ return true;
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ case EbtImage1D:
+ case EbtIImage1D:
+ case EbtUImage1D:
+ case EbtImage1DArray:
+ case EbtIImage1DArray:
+ case EbtUImage1DArray:
+ case EbtImage2DMSArray:
+ case EbtIImage2DMSArray:
+ case EbtUImage2DMSArray:
+ case EbtImageCubeArray:
+ case EbtIImageCubeArray:
+ case EbtUImageCubeArray:
+ case EbtImageRect:
+ case EbtIImageRect:
+ case EbtUImageRect:
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return false;
+ default:
+ ASSERT(!IsImage(type));
+ }
+
+ return false;
+}
+
+inline bool IsImage3D(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ return true;
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ case EbtImage1D:
+ case EbtIImage1D:
+ case EbtUImage1D:
+ case EbtImage1DArray:
+ case EbtIImage1DArray:
+ case EbtUImage1DArray:
+ case EbtImage2DMS:
+ case EbtIImage2DMS:
+ case EbtUImage2DMS:
+ case EbtImage2DMSArray:
+ case EbtIImage2DMSArray:
+ case EbtUImage2DMSArray:
+ case EbtImageCubeArray:
+ case EbtIImageCubeArray:
+ case EbtUImageCubeArray:
+ case EbtImageRect:
+ case EbtIImageRect:
+ case EbtUImageRect:
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return false;
+ default:
+ ASSERT(!IsImage(type));
+ }
+
+ return false;
+}
+
+inline bool IsImage2DArray(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ case EbtImage2DMSArray:
+ case EbtIImage2DMSArray:
+ case EbtUImage2DMSArray:
+ return true;
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ case EbtImage1D:
+ case EbtIImage1D:
+ case EbtUImage1D:
+ case EbtImage1DArray:
+ case EbtIImage1DArray:
+ case EbtUImage1DArray:
+ case EbtImage2DMS:
+ case EbtIImage2DMS:
+ case EbtUImage2DMS:
+ case EbtImageCubeArray:
+ case EbtIImageCubeArray:
+ case EbtUImageCubeArray:
+ case EbtImageRect:
+ case EbtIImageRect:
+ case EbtUImageRect:
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return false;
+ default:
+ ASSERT(!IsImage(type));
+ }
+
+ return false;
+}
+
+inline bool IsImageCube(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ return true;
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ case EbtImage1D:
+ case EbtIImage1D:
+ case EbtUImage1D:
+ case EbtImage1DArray:
+ case EbtIImage1DArray:
+ case EbtUImage1DArray:
+ case EbtImage2DMS:
+ case EbtIImage2DMS:
+ case EbtUImage2DMS:
+ case EbtImage2DMSArray:
+ case EbtIImage2DMSArray:
+ case EbtUImage2DMSArray:
+ case EbtImageCubeArray:
+ case EbtIImageCubeArray:
+ case EbtUImageCubeArray:
+ case EbtImageRect:
+ case EbtIImageRect:
+ case EbtUImageRect:
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return false;
+ default:
+ ASSERT(!IsImage(type));
+ }
+
+ return false;
+}
+
+inline bool IsImageBuffer(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsInteger(TBasicType type)
+{
+ return type == EbtInt || type == EbtUInt;
+}
+
+inline bool SupportsPrecision(TBasicType type)
+{
+ return type == EbtFloat || type == EbtInt || type == EbtUInt || IsOpaqueType(type);
+}
+
+//
+// Qualifiers and built-ins. These are mainly used to see what can be read
+// or written, and by the machine dependent translator to know which registers
+// to allocate variables in. Since built-ins tend to go to different registers
+// than varying or uniform, it makes sense they are peers, not sub-classes.
+//
+enum TQualifier
+{
+ EvqTemporary, // For temporaries (within a function), read/write
+ EvqGlobal, // For globals read/write
+ EvqConst, // User defined constants
+ EvqAttribute, // Readonly
+ EvqVaryingIn, // readonly, fragment shaders only
+ EvqVaryingOut, // vertex shaders only read/write
+ EvqUniform, // Readonly, vertex and fragment
+ EvqBuffer, // read/write, vertex, fragment and compute shader
+ EvqPatch, // EXT_tessellation_shader storage qualifier
+
+ EvqVertexIn, // Vertex shader input
+ EvqFragmentOut, // Fragment shader output
+ EvqVertexOut, // Vertex shader output
+ EvqFragmentIn, // Fragment shader input
+
+ EvqFragmentInOut, // EXT_shader_framebuffer_fetch qualifier
+
+ // parameters
+ EvqParamIn,
+ EvqParamOut,
+ EvqParamInOut,
+ EvqParamConst,
+
+ // built-ins read by vertex shader
+ EvqInstanceID,
+ EvqVertexID,
+
+ // built-ins written by vertex shader
+ EvqPosition,
+ EvqPointSize,
+
+ EvqDrawID, // ANGLE_multi_draw
+
+ // built-ins read by fragment shader
+ EvqFragCoord,
+ EvqFrontFacing,
+ EvqPointCoord,
+ EvqHelperInvocation,
+
+ // built-ins written by fragment shader
+ EvqFragColor,
+ EvqFragData,
+ EvqFragDepth, // gl_FragDepth for ESSL300, or gl_FragDepthEXT for ESSL100, EXT_frag_depth.
+
+ EvqSecondaryFragColorEXT, // EXT_blend_func_extended
+ EvqSecondaryFragDataEXT, // EXT_blend_func_extended
+
+ EvqViewIDOVR, // OVR_multiview
+ EvqViewportIndex, // gl_ViewportIndex
+
+ EvqClipDistance, // APPLE_clip_distance/EXT_clip_cull_distance
+ EvqCullDistance, // EXT_clip_cull_distance
+
+ // built-ins written by the shader_framebuffer_fetch extension(s)
+ EvqLastFragColor,
+ EvqLastFragData,
+
+ // GLSL ES 3.0 vertex output and fragment input
+ EvqSmooth, // Incomplete qualifier, smooth is the default
+ EvqFlat, // Incomplete qualifier
+ EvqNoPerspective, // Incomplete qualifier
+ EvqCentroid, // Incomplete qualifier
+ EvqSample,
+ EvqSmoothOut,
+ EvqFlatOut,
+ EvqNoPerspectiveOut,
+ EvqCentroidOut, // Implies smooth
+ EvqSampleOut,
+ EvqSmoothIn,
+ EvqFlatIn,
+ EvqNoPerspectiveIn,
+ EvqCentroidIn, // Implies smooth
+ EvqSampleIn,
+
+ // GLSL ES 3.0 extension OES_sample_variables
+ EvqSampleID,
+ EvqSamplePosition,
+ EvqSampleMaskIn,
+ EvqSampleMask,
+ EvqNumSamples,
+
+ // GLSL ES 3.1 compute shader special variables
+ EvqShared,
+ EvqComputeIn,
+ EvqNumWorkGroups,
+ EvqWorkGroupSize,
+ EvqWorkGroupID,
+ EvqLocalInvocationID,
+ EvqGlobalInvocationID,
+ EvqLocalInvocationIndex,
+
+ // GLSL ES 3.1 memory qualifiers
+ EvqReadOnly,
+ EvqWriteOnly,
+ EvqCoherent,
+ EvqRestrict,
+ EvqVolatile,
+
+ // GLSL ES 3.1 extension EXT_geometry_shader qualifiers
+ EvqGeometryIn,
+ EvqGeometryOut,
+ EvqPerVertexIn, // gl_in
+ EvqPrimitiveIDIn, // gl_PrimitiveIDIn
+ EvqInvocationID, // gl_InvocationID
+ EvqPrimitiveID, // gl_PrimitiveID
+ EvqLayerOut, // gl_Layer (GS output)
+ EvqLayerIn, // gl_Layer (FS input)
+
+ // GLSL ES 3.1 extension EXT_gpu_shader5 qualifiers
+ EvqPrecise,
+
+ // GLES ES 3.1 extension EXT_tessellation_shader qualifiers
+ EvqPatchIn,
+ EvqPatchOut,
+
+ EvqTessControlIn,
+ EvqTessControlOut,
+ EvqPerVertexOut,
+ EvqPatchVerticesIn,
+ EvqTessLevelOuter,
+ EvqTessLevelInner,
+
+ // GLES ES 3.1 extension EXT_primitive_bounding_box/OES_primitive_bounding_box
+ EvqBoundingBox,
+
+ EvqTessEvaluationIn,
+ EvqTessEvaluationOut,
+ EvqTessCoord,
+
+ // A specialization constant, which is not valid GLSL ES, but is there to support Vulkan output
+ // generation. In that case, TLayoutQualifier::location will contain the somewhat equivalent
+ // constant_id.
+ EvqSpecConst,
+
+ // end of list
+ EvqLast
+};
+
+inline bool IsQualifierUnspecified(TQualifier qualifier)
+{
+ return (qualifier == EvqTemporary || qualifier == EvqGlobal);
+}
+
+inline bool IsStorageBuffer(TQualifier qualifier)
+{
+ return qualifier == EvqBuffer;
+}
+
+inline bool IsShaderIn(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqVertexIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ case EvqGeometryIn:
+ case EvqFragmentIn:
+ case EvqPerVertexIn:
+ case EvqAttribute:
+ case EvqVaryingIn:
+ case EvqSmoothIn:
+ case EvqFlatIn:
+ case EvqNoPerspectiveIn:
+ case EvqCentroidIn:
+ case EvqSampleIn:
+ case EvqPatchIn:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsShaderOut(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqVertexOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ case EvqGeometryOut:
+ case EvqFragmentOut:
+ case EvqPerVertexOut:
+ case EvqVaryingOut:
+ case EvqSmoothOut:
+ case EvqFlatOut:
+ case EvqNoPerspectiveOut:
+ case EvqCentroidOut:
+ case EvqSampleOut:
+ case EvqPatchOut:
+ case EvqFragmentInOut:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsShaderIoBlock(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqPerVertexIn:
+ case EvqPerVertexOut:
+ case EvqVertexOut:
+ case EvqTessControlIn:
+ case EvqTessControlOut:
+ case EvqTessEvaluationIn:
+ case EvqTessEvaluationOut:
+ case EvqPatchIn:
+ case EvqPatchOut:
+ case EvqGeometryIn:
+ case EvqGeometryOut:
+ case EvqFragmentIn:
+ return true;
+ default:
+ return false;
+ }
+}
+
+enum TLayoutImageInternalFormat
+{
+ EiifUnspecified,
+ EiifRGBA32F,
+ EiifRGBA16F,
+ EiifR32F,
+ EiifRGBA32UI,
+ EiifRGBA16UI,
+ EiifRGBA8UI,
+ EiifR32UI,
+ EiifRGBA32I,
+ EiifRGBA16I,
+ EiifRGBA8I,
+ EiifR32I,
+ EiifRGBA8,
+ EiifRGBA8_SNORM,
+
+ EiifLast = EiifRGBA8_SNORM,
+};
+
+enum TLayoutMatrixPacking
+{
+ EmpUnspecified,
+ EmpRowMajor,
+ EmpColumnMajor,
+
+ EmpLast = EmpColumnMajor,
+};
+
+enum TLayoutBlockStorage
+{
+ EbsUnspecified,
+ EbsShared,
+ EbsPacked,
+ EbsStd140,
+ EbsStd430,
+
+ EbsLast = EbsStd430,
+};
+
+enum TYuvCscStandardEXT
+{
+ EycsUndefined,
+ EycsItu601,
+ EycsItu601FullRange,
+ EycsItu709
+};
+
+enum TLayoutPrimitiveType
+{
+ EptUndefined,
+ EptPoints,
+ EptLines,
+ EptLinesAdjacency,
+ EptTriangles,
+ EptTrianglesAdjacency,
+ EptLineStrip,
+ EptTriangleStrip
+};
+
+enum TLayoutTessEvaluationType
+{
+ EtetUndefined,
+ EtetTriangles,
+ EtetQuads,
+ EtetIsolines,
+ EtetEqualSpacing,
+ EtetFractionalEvenSpacing,
+ EtetFractionalOddSpacing,
+ EtetCw,
+ EtetCcw,
+ EtetPointMode
+};
+
+class AdvancedBlendEquations
+{
+ public:
+ // Must have a trivial default constructor since it is used in YYSTYPE.
+ AdvancedBlendEquations() = default;
+ explicit constexpr AdvancedBlendEquations(uint32_t initialState)
+ : mEnabledBlendEquations(initialState)
+ {}
+
+ bool any() const;
+ bool anyHsl() const;
+
+ void setAll();
+ void reset() { mEnabledBlendEquations = 0; }
+
+ // Parameter is gl::BlendEquationType, but PackedEnums.h include is not possible here.
+ void set(uint32_t blendEquation);
+
+ uint32_t bits() const { return mEnabledBlendEquations; }
+
+ AdvancedBlendEquations operator|=(AdvancedBlendEquations other)
+ {
+ mEnabledBlendEquations |= other.mEnabledBlendEquations;
+ return *this;
+ }
+
+ private:
+ uint32_t mEnabledBlendEquations;
+};
+
+struct TLayoutQualifier
+{
+ // Must have a trivial default constructor since it is used in YYSTYPE.
+ TLayoutQualifier() = default;
+
+ constexpr static TLayoutQualifier Create() { return TLayoutQualifier(0); }
+
+ bool isEmpty() const
+ {
+ return location == -1 && binding == -1 && offset == -1 && numViews == -1 && yuv == false &&
+ earlyFragmentTests == false && matrixPacking == EmpUnspecified &&
+ blockStorage == EbsUnspecified && !localSize.isAnyValueSet() &&
+ imageInternalFormat == EiifUnspecified && primitiveType == EptUndefined &&
+ invocations == 0 && maxVertices == -1 && vertices == 0 &&
+ tesPrimitiveType == EtetUndefined && tesVertexSpacingType == EtetUndefined &&
+ tesOrderingType == EtetUndefined && tesPointType == EtetUndefined && index == -1 &&
+ inputAttachmentIndex == -1 && noncoherent == false &&
+ !advancedBlendEquations.any() && !pushConstant;
+ }
+
+ bool isCombinationValid() const
+ {
+ bool workGroupSizeSpecified = localSize.isAnyValueSet();
+ bool numViewsSet = (numViews != -1);
+ bool geometryShaderSpecified =
+ (primitiveType != EptUndefined) || (invocations != 0) || (maxVertices != -1);
+ bool subpassInputSpecified = (inputAttachmentIndex != -1);
+ bool otherLayoutQualifiersSpecified =
+ (location != -1 || binding != -1 || index != -1 || matrixPacking != EmpUnspecified ||
+ blockStorage != EbsUnspecified || imageInternalFormat != EiifUnspecified);
+ bool blendEquationSpecified = advancedBlendEquations.any();
+
+ // we can have either the work group size specified, or number of views,
+ // or yuv layout qualifier, or early_fragment_tests layout qualifier, or the other layout
+ // qualifiers.
+ return (workGroupSizeSpecified ? 1 : 0) + (numViewsSet ? 1 : 0) + (yuv ? 1 : 0) +
+ (earlyFragmentTests ? 1 : 0) + (otherLayoutQualifiersSpecified ? 1 : 0) +
+ (geometryShaderSpecified ? 1 : 0) + (subpassInputSpecified ? 1 : 0) +
+ (noncoherent ? 1 : 0) + (blendEquationSpecified ? 1 : 0) <=
+ 1;
+ }
+
+ bool isLocalSizeEqual(const WorkGroupSize &localSizeIn) const
+ {
+ return localSize.isWorkGroupSizeMatching(localSizeIn);
+ }
+
+ int location;
+ unsigned int locationsSpecified;
+ TLayoutMatrixPacking matrixPacking;
+ TLayoutBlockStorage blockStorage;
+
+ // Compute shader layout qualifiers.
+ WorkGroupSize localSize;
+
+ int binding;
+ int offset;
+
+ bool pushConstant;
+
+ // Image format layout qualifier
+ TLayoutImageInternalFormat imageInternalFormat;
+
+ // OVR_multiview num_views.
+ int numViews;
+
+ // EXT_YUV_target yuv layout qualifier.
+ bool yuv;
+
+ // early_fragment_tests qualifier.
+ bool earlyFragmentTests;
+
+ // OES_geometry_shader layout qualifiers.
+ TLayoutPrimitiveType primitiveType;
+ int invocations;
+ int maxVertices;
+
+ // EXT_tessellation_shader shader layout qualifiers
+ int vertices;
+ TLayoutTessEvaluationType tesPrimitiveType;
+ TLayoutTessEvaluationType tesVertexSpacingType;
+ TLayoutTessEvaluationType tesOrderingType;
+ TLayoutTessEvaluationType tesPointType;
+
+ // EXT_blend_func_extended fragment output layout qualifier
+ int index;
+
+ // EXT_shader_framebuffer_fetch layout qualifiers.
+ int inputAttachmentIndex;
+ bool noncoherent;
+
+ // KHR_blend_equation_advanced layout qualifiers.
+ AdvancedBlendEquations advancedBlendEquations;
+
+ // D3D 11.3 Rasterizer Order Views (ROVs).
+ // This qualifier is only used internally by ANGLE; it is not visible to the application.
+ bool rasterOrdered;
+
+ private:
+ explicit constexpr TLayoutQualifier(int /*placeholder*/)
+ : location(-1),
+ locationsSpecified(0),
+ matrixPacking(EmpUnspecified),
+ blockStorage(EbsUnspecified),
+ localSize(-1),
+ binding(-1),
+ offset(-1),
+ pushConstant(false),
+ imageInternalFormat(EiifUnspecified),
+ numViews(-1),
+ yuv(false),
+ earlyFragmentTests(false),
+ primitiveType(EptUndefined),
+ invocations(0),
+ maxVertices(-1),
+ vertices(0),
+ tesPrimitiveType(EtetUndefined),
+ tesVertexSpacingType(EtetUndefined),
+ tesOrderingType(EtetUndefined),
+ tesPointType(EtetUndefined),
+ index(-1),
+ inputAttachmentIndex(-1),
+ noncoherent(false),
+ advancedBlendEquations(0),
+ rasterOrdered(false)
+ {}
+};
+
+struct TMemoryQualifier
+{
+ // Must have a trivial default constructor since it is used in YYSTYPE.
+ TMemoryQualifier() = default;
+
+ bool isEmpty() const
+ {
+ return !readonly && !writeonly && !coherent && !restrictQualifier && !volatileQualifier;
+ }
+
+ constexpr static TMemoryQualifier Create() { return TMemoryQualifier(0); }
+
+ // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
+ // An image can be qualified as both readonly and writeonly. It still can be can be used with
+ // imageSize().
+ bool readonly;
+ bool writeonly;
+ bool coherent;
+
+ // restrict and volatile are reserved keywords in C/C++
+ bool restrictQualifier;
+ bool volatileQualifier;
+
+ private:
+ explicit constexpr TMemoryQualifier(int /*placeholder*/)
+ : readonly(false),
+ writeonly(false),
+ coherent(false),
+ restrictQualifier(false),
+ volatileQualifier(false)
+ {}
+};
+
+inline const char *getWorkGroupSizeString(size_t dimension)
+{
+ switch (dimension)
+ {
+ case 0u:
+ return "local_size_x";
+ case 1u:
+ return "local_size_y";
+ case 2u:
+ return "local_size_z";
+ default:
+ UNREACHABLE();
+ return "dimension out of bounds";
+ }
+}
+
+// Used for GLSL generation, debugging and error messages.
+inline const char *getQualifierString(TQualifier q)
+{
+ // clang-format off
+ switch(q)
+ {
+ case EvqTemporary: return "Temporary";
+ case EvqGlobal: return "Global";
+ case EvqConst: return "const";
+ case EvqAttribute: return "attribute";
+ case EvqVaryingIn: return "varying";
+ case EvqVaryingOut: return "varying";
+ case EvqUniform: return "uniform";
+ case EvqBuffer: return "buffer";
+ case EvqPatch: return "patch";
+ case EvqVertexIn: return "in";
+ case EvqFragmentOut: return "out";
+ case EvqVertexOut: return "out";
+ case EvqFragmentIn: return "in";
+ case EvqParamIn: return "in";
+ case EvqParamOut: return "out";
+ case EvqParamInOut: return "inout";
+ case EvqParamConst: return "const";
+ case EvqInstanceID: return "InstanceID";
+ case EvqVertexID: return "VertexID";
+ case EvqPosition: return "Position";
+ case EvqPointSize: return "PointSize";
+ case EvqDrawID: return "DrawID";
+ case EvqFragCoord: return "FragCoord";
+ case EvqFrontFacing: return "FrontFacing";
+ case EvqHelperInvocation: return "HelperInvocation";
+ case EvqPointCoord: return "PointCoord";
+ case EvqFragColor: return "FragColor";
+ case EvqFragData: return "FragData";
+ case EvqFragDepth: return "FragDepth";
+ case EvqSecondaryFragColorEXT: return "SecondaryFragColorEXT";
+ case EvqSecondaryFragDataEXT: return "SecondaryFragDataEXT";
+ case EvqViewIDOVR: return "ViewIDOVR";
+ case EvqViewportIndex: return "ViewportIndex";
+ case EvqLayerOut: return "LayerOut";
+ case EvqLayerIn: return "LayerIn";
+ case EvqLastFragColor: return "LastFragColor";
+ case EvqLastFragData: return "LastFragData";
+ case EvqFragmentInOut: return "inout";
+ case EvqSmoothOut: return "smooth out";
+ case EvqCentroidOut: return "smooth centroid out";
+ case EvqFlatOut: return "flat out";
+ case EvqNoPerspectiveOut: return "noperspective out";
+ case EvqSmoothIn: return "smooth in";
+ case EvqFlatIn: return "flat in";
+ case EvqNoPerspectiveIn: return "noperspective in";
+ case EvqCentroidIn: return "smooth centroid in";
+ case EvqCentroid: return "centroid";
+ case EvqFlat: return "flat";
+ case EvqNoPerspective: return "noperspective";
+ case EvqSmooth: return "smooth";
+ case EvqShared: return "shared";
+ case EvqComputeIn: return "in";
+ case EvqNumWorkGroups: return "NumWorkGroups";
+ case EvqWorkGroupSize: return "WorkGroupSize";
+ case EvqWorkGroupID: return "WorkGroupID";
+ case EvqLocalInvocationID: return "LocalInvocationID";
+ case EvqGlobalInvocationID: return "GlobalInvocationID";
+ case EvqLocalInvocationIndex: return "LocalInvocationIndex";
+ case EvqReadOnly: return "readonly";
+ case EvqWriteOnly: return "writeonly";
+ case EvqGeometryIn: return "in";
+ case EvqGeometryOut: return "out";
+ case EvqPerVertexIn: return "gl_in";
+ case EvqPrimitiveIDIn: return "gl_PrimitiveIDIn";
+ case EvqInvocationID: return "gl_InvocationID";
+ case EvqPrimitiveID: return "gl_PrimitiveID";
+ case EvqPrecise: return "precise";
+ case EvqClipDistance: return "ClipDistance";
+ case EvqCullDistance: return "CullDistance";
+ case EvqSample: return "sample";
+ case EvqSampleIn: return "sample in";
+ case EvqSampleOut: return "sample out";
+ case EvqSampleID: return "SampleID";
+ case EvqSamplePosition: return "SamplePosition";
+ case EvqSampleMaskIn: return "SampleMaskIn";
+ case EvqSampleMask: return "SampleMask";
+ case EvqNumSamples: return "NumSamples";
+ case EvqPatchIn: return "patch in";
+ case EvqPatchOut: return "patch out";
+ case EvqTessControlIn: return "in";
+ case EvqTessControlOut: return "out";
+ case EvqPerVertexOut: return "gl_out";
+ case EvqPatchVerticesIn: return "PatchVerticesIn";
+ case EvqTessLevelOuter: return "TessLevelOuter";
+ case EvqTessLevelInner: return "TessLevelInner";
+ case EvqBoundingBox: return "BoundingBox";
+ case EvqTessEvaluationIn: return "in";
+ case EvqTessEvaluationOut: return "out";
+ case EvqTessCoord: return "TessCoord";
+ case EvqSpecConst: return "const";
+ default: UNREACHABLE(); return "unknown qualifier";
+ }
+ // clang-format on
+}
+
+inline const char *getMatrixPackingString(TLayoutMatrixPacking mpq)
+{
+ switch (mpq)
+ {
+ case EmpUnspecified:
+ return "mp_unspecified";
+ case EmpRowMajor:
+ return "row_major";
+ case EmpColumnMajor:
+ return "column_major";
+ default:
+ UNREACHABLE();
+ return "unknown matrix packing";
+ }
+}
+
+inline const char *getBlockStorageString(TLayoutBlockStorage bsq)
+{
+ switch (bsq)
+ {
+ case EbsUnspecified:
+ return "bs_unspecified";
+ case EbsShared:
+ return "shared";
+ case EbsPacked:
+ return "packed";
+ case EbsStd140:
+ return "std140";
+ case EbsStd430:
+ return "std430";
+ default:
+ UNREACHABLE();
+ return "unknown block storage";
+ }
+}
+
+inline const char *getImageInternalFormatString(TLayoutImageInternalFormat iifq)
+{
+ switch (iifq)
+ {
+ case EiifRGBA32F:
+ return "rgba32f";
+ case EiifRGBA16F:
+ return "rgba16f";
+ case EiifR32F:
+ return "r32f";
+ case EiifRGBA32UI:
+ return "rgba32ui";
+ case EiifRGBA16UI:
+ return "rgba16ui";
+ case EiifRGBA8UI:
+ return "rgba8ui";
+ case EiifR32UI:
+ return "r32ui";
+ case EiifRGBA32I:
+ return "rgba32i";
+ case EiifRGBA16I:
+ return "rgba16i";
+ case EiifRGBA8I:
+ return "rgba8i";
+ case EiifR32I:
+ return "r32i";
+ case EiifRGBA8:
+ return "rgba8";
+ case EiifRGBA8_SNORM:
+ return "rgba8_snorm";
+ default:
+ UNREACHABLE();
+ return "unknown internal image format";
+ }
+}
+
+inline TYuvCscStandardEXT getYuvCscStandardEXT(const ImmutableString &str)
+{
+ if (str == "itu_601")
+ return EycsItu601;
+ else if (str == "itu_601_full_range")
+ return EycsItu601FullRange;
+ else if (str == "itu_709")
+ return EycsItu709;
+ return EycsUndefined;
+}
+
+inline const char *getYuvCscStandardEXTString(TYuvCscStandardEXT ycsq)
+{
+ switch (ycsq)
+ {
+ case EycsItu601:
+ return "itu_601";
+ case EycsItu601FullRange:
+ return "itu_601_full_range";
+ case EycsItu709:
+ return "itu_709";
+ default:
+ UNREACHABLE();
+ return "unknown color space conversion standard";
+ }
+}
+
+inline const char *getGeometryShaderPrimitiveTypeString(TLayoutPrimitiveType primitiveType)
+{
+ switch (primitiveType)
+ {
+ case EptPoints:
+ return "points";
+ case EptLines:
+ return "lines";
+ case EptTriangles:
+ return "triangles";
+ case EptLinesAdjacency:
+ return "lines_adjacency";
+ case EptTrianglesAdjacency:
+ return "triangles_adjacency";
+ case EptLineStrip:
+ return "line_strip";
+ case EptTriangleStrip:
+ return "triangle_strip";
+ default:
+ UNREACHABLE();
+ return "unknown geometry shader primitive type";
+ }
+}
+
+inline const char *getTessEvaluationShaderTypeString(TLayoutTessEvaluationType type)
+{
+ switch (type)
+ {
+ case EtetTriangles:
+ return "triangles";
+ case EtetQuads:
+ return "quads";
+ case EtetIsolines:
+ return "isolines";
+ case EtetEqualSpacing:
+ return "equal_spacing";
+ case EtetFractionalEvenSpacing:
+ return "fractional_even_spacing";
+ case EtetFractionalOddSpacing:
+ return "fractional_odd_spacing";
+ case EtetCw:
+ return "cw";
+ case EtetCcw:
+ return "ccw";
+ case EtetPointMode:
+ return "point_mode";
+ default:
+ UNREACHABLE();
+ return "unknown tessellation evaluation shader variable type";
+ }
+}
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_BASETYPES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp
new file mode 100644
index 0000000000..34b43365cf
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp
@@ -0,0 +1,161 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "angle_gl.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
+{
+ public:
+ BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator &emulator)
+ : TIntermTraverser(true, false, false), mEmulator(emulator)
+ {}
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override
+ {
+ if (node->getFunction())
+ {
+ bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());
+ if (needToEmulate)
+ node->setUseEmulatedFunction();
+ }
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ // Here we handle all the math built-in functions, not just the ones that are currently
+ // identified as problematic.
+ if (!BuiltInGroup::IsMath(node->getOp()))
+ {
+ return true;
+ }
+ bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());
+ if (needToEmulate)
+ node->setUseEmulatedFunction();
+ return true;
+ }
+
+ private:
+ BuiltInFunctionEmulator &mEmulator;
+};
+
+BuiltInFunctionEmulator::BuiltInFunctionEmulator() {}
+
+void BuiltInFunctionEmulator::addEmulatedFunction(const TSymbolUniqueId &uniqueId,
+ const char *emulatedFunctionDefinition)
+{
+ mEmulatedFunctions[uniqueId.get()] = std::string(emulatedFunctionDefinition);
+}
+
+void BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(
+ const TSymbolUniqueId &dependency,
+ const TSymbolUniqueId &uniqueId,
+ const char *emulatedFunctionDefinition)
+{
+ mEmulatedFunctions[uniqueId.get()] = std::string(emulatedFunctionDefinition);
+ mFunctionDependencies[uniqueId.get()] = dependency.get();
+}
+
+bool BuiltInFunctionEmulator::isOutputEmpty() const
+{
+ return (mFunctions.size() == 0);
+}
+
+void BuiltInFunctionEmulator::outputEmulatedFunctions(TInfoSinkBase &out) const
+{
+ for (const auto &function : mFunctions)
+ {
+ const char *body = findEmulatedFunction(function);
+ ASSERT(body);
+ out << body;
+ out << "\n\n";
+ }
+}
+
+const char *BuiltInFunctionEmulator::findEmulatedFunction(int uniqueId) const
+{
+ for (const auto &queryFunction : mQueryFunctions)
+ {
+ const char *result = queryFunction(uniqueId);
+ if (result)
+ {
+ return result;
+ }
+ }
+
+ const auto &result = mEmulatedFunctions.find(uniqueId);
+ if (result != mEmulatedFunctions.end())
+ {
+ return result->second.c_str();
+ }
+
+ return nullptr;
+}
+
+bool BuiltInFunctionEmulator::setFunctionCalled(const TFunction *function)
+{
+ ASSERT(function != nullptr);
+ return setFunctionCalled(function->uniqueId().get());
+}
+
+bool BuiltInFunctionEmulator::setFunctionCalled(int uniqueId)
+{
+ if (!findEmulatedFunction(uniqueId))
+ {
+ return false;
+ }
+
+ for (size_t i = 0; i < mFunctions.size(); ++i)
+ {
+ if (mFunctions[i] == uniqueId)
+ return true;
+ }
+ // If the function depends on another, mark the dependency as called.
+ auto dependency = mFunctionDependencies.find(uniqueId);
+ if (dependency != mFunctionDependencies.end())
+ {
+ setFunctionCalled((*dependency).second);
+ }
+ mFunctions.push_back(uniqueId);
+ return true;
+}
+
+void BuiltInFunctionEmulator::markBuiltInFunctionsForEmulation(TIntermNode *root)
+{
+ ASSERT(root);
+
+ if (mEmulatedFunctions.empty() && mQueryFunctions.empty())
+ return;
+
+ BuiltInFunctionEmulationMarker marker(*this);
+ root->traverse(&marker);
+}
+
+void BuiltInFunctionEmulator::cleanup()
+{
+ mFunctions.clear();
+ mFunctionDependencies.clear();
+}
+
+void BuiltInFunctionEmulator::addFunctionMap(BuiltinQueryFunc queryFunc)
+{
+ mQueryFunctions.push_back(queryFunc);
+}
+
+// static
+void BuiltInFunctionEmulator::WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name)
+{
+ ASSERT(name[strlen(name) - 1] != '(');
+ out << name << "_emu";
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h
new file mode 100644
index 0000000000..7ebd6bc087
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h
@@ -0,0 +1,80 @@
+//
+// Copyright 2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
+#define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
+
+#include "compiler/translator/InfoSink.h"
+
+namespace sh
+{
+
+class TIntermNode;
+class TFunction;
+class TSymbolUniqueId;
+
+using BuiltinQueryFunc = const char *(int);
+
+//
+// This class decides which built-in functions need to be replaced with the emulated ones. It can be
+// used to work around driver bugs or implement functions that are not natively implemented on a
+// specific platform.
+//
+class BuiltInFunctionEmulator
+{
+ public:
+ BuiltInFunctionEmulator();
+
+ void markBuiltInFunctionsForEmulation(TIntermNode *root);
+
+ void cleanup();
+
+ // "name" gets written as "name_emu".
+ static void WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name);
+
+ bool isOutputEmpty() const;
+
+ // Output function emulation definition. This should be before any other shader source.
+ void outputEmulatedFunctions(TInfoSinkBase &out) const;
+
+ // Add functions that need to be emulated.
+ void addEmulatedFunction(const TSymbolUniqueId &uniqueId,
+ const char *emulatedFunctionDefinition);
+
+ void addEmulatedFunctionWithDependency(const TSymbolUniqueId &dependency,
+ const TSymbolUniqueId &uniqueId,
+ const char *emulatedFunctionDefinition);
+
+ void addFunctionMap(BuiltinQueryFunc queryFunc);
+
+ private:
+ class BuiltInFunctionEmulationMarker;
+
+ // Records that a function is called by the shader and might need to be emulated. If the
+ // function is not in mEmulatedFunctions, this becomes a no-op. Returns true if the function
+ // call needs to be replaced with an emulated one.
+ bool setFunctionCalled(const TFunction *function);
+ bool setFunctionCalled(int uniqueId);
+
+ const char *findEmulatedFunction(int uniqueId) const;
+
+ // Map from function unique id to emulated function definition
+ std::map<int, std::string> mEmulatedFunctions;
+
+ // Map from dependent functions to their dependencies. This structure allows each function to
+ // have at most one dependency.
+ std::map<int, int> mFunctionDependencies;
+
+ // Called function ids
+ std::vector<int> mFunctions;
+
+ // Constexpr function tables.
+ std::vector<BuiltinQueryFunc *> mQueryFunctions;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
new file mode 100644
index 0000000000..9212336585
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
@@ -0,0 +1,284 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/VersionGLSL.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+
+namespace sh
+{
+
+void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
+ sh::GLenum shaderType)
+{
+ if (shaderType == GL_VERTEX_SHADER)
+ {
+ emu->addEmulatedFunction(BuiltInId::abs_Int1, "int abs_emu(int x) { return x * sign(x); }");
+ }
+}
+
+void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
+ int targetGLSLVersion)
+{
+ // isnan() is supported since GLSL 1.3.
+ if (targetGLSLVersion < GLSL_VERSION_130)
+ return;
+
+ // !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false.
+ emu->addEmulatedFunction(
+ BuiltInId::isnan_Float1,
+ "bool isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }");
+ emu->addEmulatedFunction(
+ BuiltInId::isnan_Float2,
+ "bvec2 isnan_emu(vec2 x)\n"
+ "{\n"
+ " bvec2 isnan;\n"
+ " for (int i = 0; i < 2; i++)\n"
+ " {\n"
+ " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
+ " }\n"
+ " return isnan;\n"
+ "}\n");
+ emu->addEmulatedFunction(
+ BuiltInId::isnan_Float3,
+ "bvec3 isnan_emu(vec3 x)\n"
+ "{\n"
+ " bvec3 isnan;\n"
+ " for (int i = 0; i < 3; i++)\n"
+ " {\n"
+ " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
+ " }\n"
+ " return isnan;\n"
+ "}\n");
+ emu->addEmulatedFunction(
+ BuiltInId::isnan_Float4,
+ "bvec4 isnan_emu(vec4 x)\n"
+ "{\n"
+ " bvec4 isnan;\n"
+ " for (int i = 0; i < 4; i++)\n"
+ " {\n"
+ " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
+ " }\n"
+ " return isnan;\n"
+ "}\n");
+}
+
+void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu)
+{
+ emu->addEmulatedFunction(BuiltInId::atan_Float1_Float1,
+ "emu_precision float atan_emu(emu_precision float y, emu_precision "
+ "float x)\n"
+ "{\n"
+ " if (x > 0.0) return atan(y / x);\n"
+ " else if (x < 0.0 && y >= 0.0) return atan(y / x) + 3.14159265;\n"
+ " else if (x < 0.0 && y < 0.0) return atan(y / x) - 3.14159265;\n"
+ " else return 1.57079632 * sign(y);\n"
+ "}\n");
+ static const std::array<TSymbolUniqueId, 4> ids = {
+ BuiltInId::atan_Float1_Float1,
+ BuiltInId::atan_Float2_Float2,
+ BuiltInId::atan_Float3_Float3,
+ BuiltInId::atan_Float4_Float4,
+ };
+ for (int dim = 2; dim <= 4; ++dim)
+ {
+ std::stringstream ss = sh::InitializeStream<std::stringstream>();
+ ss << "emu_precision vec" << dim << " atan_emu(emu_precision vec" << dim
+ << " y, emu_precision vec" << dim << " x)\n"
+ << "{\n"
+ " return vec"
+ << dim << "(";
+ for (int i = 0; i < dim; ++i)
+ {
+ ss << "atan_emu(y[" << i << "], x[" << i << "])";
+ if (i < dim - 1)
+ {
+ ss << ", ";
+ }
+ }
+ ss << ");\n"
+ "}\n";
+ emu->addEmulatedFunctionWithDependency(BuiltInId::atan_Float1_Float1, ids[dim - 1],
+ ss.str().c_str());
+ }
+}
+
+// Emulate built-in functions missing from GLSL 1.30 and higher
+void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu,
+ sh::GLenum shaderType,
+ int targetGLSLVersion)
+{
+ // Emulate packUnorm2x16 and unpackUnorm2x16 (GLSL 4.10)
+ if (targetGLSLVersion < GLSL_VERSION_410)
+ {
+ // clang-format off
+ emu->addEmulatedFunction(BuiltInId::packUnorm2x16_Float2,
+ "uint packUnorm2x16_emu(vec2 v)\n"
+ "{\n"
+ " int x = int(round(clamp(v.x, 0.0, 1.0) * 65535.0));\n"
+ " int y = int(round(clamp(v.y, 0.0, 1.0) * 65535.0));\n"
+ " return uint((y << 16) | (x & 0xFFFF));\n"
+ "}\n");
+
+ emu->addEmulatedFunction(BuiltInId::unpackUnorm2x16_UInt1,
+ "vec2 unpackUnorm2x16_emu(uint u)\n"
+ "{\n"
+ " float x = float(u & 0xFFFFu) / 65535.0;\n"
+ " float y = float(u >> 16) / 65535.0;\n"
+ " return vec2(x, y);\n"
+ "}\n");
+ // clang-format on
+ }
+
+ // Emulate packSnorm2x16, packHalf2x16, unpackSnorm2x16, and unpackHalf2x16 (GLSL 4.20)
+ // by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30).
+ if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420)
+ {
+ // clang-format off
+ emu->addEmulatedFunction(BuiltInId::packSnorm2x16_Float2,
+ "uint packSnorm2x16_emu(vec2 v)\n"
+ "{\n"
+ " #if defined(GL_ARB_shading_language_packing)\n"
+ " return packSnorm2x16(v);\n"
+ " #else\n"
+ " int x = int(round(clamp(v.x, -1.0, 1.0) * 32767.0));\n"
+ " int y = int(round(clamp(v.y, -1.0, 1.0) * 32767.0));\n"
+ " return uint((y << 16) | (x & 0xFFFF));\n"
+ " #endif\n"
+ "}\n");
+ emu->addEmulatedFunction(BuiltInId::unpackSnorm2x16_UInt1,
+ "#if !defined(GL_ARB_shading_language_packing)\n"
+ " float fromSnorm(uint x)\n"
+ " {\n"
+ " int xi = (int(x) & 0x7FFF) - (int(x) & 0x8000);\n"
+ " return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
+ " }\n"
+ "#endif\n"
+ "\n"
+ "vec2 unpackSnorm2x16_emu(uint u)\n"
+ "{\n"
+ " #if defined(GL_ARB_shading_language_packing)\n"
+ " return unpackSnorm2x16(u);\n"
+ " #else\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u;\n"
+ " return vec2(fromSnorm(x), fromSnorm(y));\n"
+ " #endif\n"
+ "}\n");
+ // Functions uint f32tof16(float val) and float f16tof32(uint val) are
+ // based on the OpenGL redbook Appendix Session "Floating-Point Formats Used in OpenGL".
+ emu->addEmulatedFunction(BuiltInId::packHalf2x16_Float2,
+ "#if !defined(GL_ARB_shading_language_packing)\n"
+ " uint f32tof16(float val)\n"
+ " {\n"
+ " uint f32 = floatBitsToUint(val);\n"
+ " uint f16 = 0u;\n"
+ " uint sign = (f32 >> 16) & 0x8000u;\n"
+ " int exponent = int((f32 >> 23) & 0xFFu) - 127;\n"
+ " uint mantissa = f32 & 0x007FFFFFu;\n"
+ " if (exponent == 128)\n"
+ " {\n"
+ " // Infinity or NaN\n"
+ " // NaN bits that are masked out by 0x3FF get discarded.\n"
+ " // This can turn some NaNs to infinity, but this is allowed by the spec.\n"
+ " f16 = sign | (0x1Fu << 10);\n"
+ " f16 |= (mantissa & 0x3FFu);\n"
+ " }\n"
+ " else if (exponent > 15)\n"
+ " {\n"
+ " // Overflow - flush to Infinity\n"
+ " f16 = sign | (0x1Fu << 10);\n"
+ " }\n"
+ " else if (exponent > -15)\n"
+ " {\n"
+ " // Representable value\n"
+ " exponent += 15;\n"
+ " mantissa >>= 13;\n"
+ " f16 = sign | uint(exponent << 10) | mantissa;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " f16 = sign;\n"
+ " }\n"
+ " return f16;\n"
+ " }\n"
+ "#endif\n"
+ "\n"
+ "uint packHalf2x16_emu(vec2 v)\n"
+ "{\n"
+ " #if defined(GL_ARB_shading_language_packing)\n"
+ " return packHalf2x16(v);\n"
+ " #else\n"
+ " uint x = f32tof16(v.x);\n"
+ " uint y = f32tof16(v.y);\n"
+ " return (y << 16) | x;\n"
+ " #endif\n"
+ "}\n");
+ emu->addEmulatedFunction(BuiltInId::unpackHalf2x16_UInt1,
+ "#if !defined(GL_ARB_shading_language_packing)\n"
+ " float f16tof32(uint val)\n"
+ " {\n"
+ " uint sign = (val & 0x8000u) << 16;\n"
+ " int exponent = int((val & 0x7C00u) >> 10);\n"
+ " uint mantissa = val & 0x03FFu;\n"
+ " float f32 = 0.0;\n"
+ " if(exponent == 0)\n"
+ " {\n"
+ " if (mantissa != 0u)\n"
+ " {\n"
+ " const float scale = 1.0 / (1 << 24);\n"
+ " f32 = scale * mantissa;\n"
+ " }\n"
+ " }\n"
+ " else if (exponent == 31)\n"
+ " {\n"
+ " return uintBitsToFloat(sign | 0x7F800000u | mantissa);\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " exponent -= 15;\n"
+ " float scale;\n"
+ " if(exponent < 0)\n"
+ " {\n"
+ " // The negative unary operator is buggy on OSX.\n"
+ " // Work around this by using abs instead.\n"
+ " scale = 1.0 / (1 << abs(exponent));\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " scale = 1 << exponent;\n"
+ " }\n"
+ " float decimal = 1.0 + float(mantissa) / float(1 << 10);\n"
+ " f32 = scale * decimal;\n"
+ " }\n"
+ "\n"
+ " if (sign != 0u)\n"
+ " {\n"
+ " f32 = -f32;\n"
+ " }\n"
+ "\n"
+ " return f32;\n"
+ " }\n"
+ "#endif\n"
+ "\n"
+ "vec2 unpackHalf2x16_emu(uint u)\n"
+ "{\n"
+ " #if defined(GL_ARB_shading_language_packing)\n"
+ " return unpackHalf2x16(u);\n"
+ " #else\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u & 0xFFFFu;\n"
+ " return vec2(f16tof32(x), f16tof32(y));\n"
+ " #endif\n"
+ "}\n");
+ // clang-format on
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h
new file mode 100644
index 0000000000..91ba67f3aa
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h
@@ -0,0 +1,40 @@
+//
+// Copyright 2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
+#define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+namespace sh
+{
+class BuiltInFunctionEmulator;
+
+//
+// This works around bug in Intel Mac drivers.
+//
+void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
+ sh::GLenum shaderType);
+
+//
+// This works around isnan() bug in Intel Mac drivers
+//
+void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
+ int targetGLSLVersion);
+//
+// This works around atan(y, x) bug in NVIDIA drivers.
+//
+void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu);
+
+//
+// This function is emulating built-in functions missing from GLSL 1.30 and higher.
+//
+void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu,
+ sh::GLenum shaderType,
+ int targetGLSLVersion);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
new file mode 100644
index 0000000000..66a0be39e7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
@@ -0,0 +1,173 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
+#include "angle_gl.h"
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/VersionGLSL.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+
+namespace sh
+{
+
+// Defined in emulated_builtin_functions_hlsl_autogen.cpp.
+const char *FindHLSLFunction(int uniqueId);
+
+void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
+ int targetGLSLVersion)
+{
+ if (targetGLSLVersion < GLSL_VERSION_130)
+ return;
+
+ emu->addEmulatedFunction(BuiltInId::isnan_Float1,
+ "bool isnan_emu(float x)\n"
+ "{\n"
+ " return (x > 0.0 || x < 0.0) ? false : x != 0.0;\n"
+ "}\n"
+ "\n");
+
+ emu->addEmulatedFunction(
+ BuiltInId::isnan_Float2,
+ "bool2 isnan_emu(float2 x)\n"
+ "{\n"
+ " bool2 isnan;\n"
+ " for (int i = 0; i < 2; i++)\n"
+ " {\n"
+ " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
+ " }\n"
+ " return isnan;\n"
+ "}\n");
+
+ emu->addEmulatedFunction(
+ BuiltInId::isnan_Float3,
+ "bool3 isnan_emu(float3 x)\n"
+ "{\n"
+ " bool3 isnan;\n"
+ " for (int i = 0; i < 3; i++)\n"
+ " {\n"
+ " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
+ " }\n"
+ " return isnan;\n"
+ "}\n");
+
+ emu->addEmulatedFunction(
+ BuiltInId::isnan_Float4,
+ "bool4 isnan_emu(float4 x)\n"
+ "{\n"
+ " bool4 isnan;\n"
+ " for (int i = 0; i < 4; i++)\n"
+ " {\n"
+ " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
+ " }\n"
+ " return isnan;\n"
+ "}\n");
+}
+
+void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
+{
+ emu->addFunctionMap(FindHLSLFunction);
+
+ // (a + b2^16) * (c + d2^16) = ac + (ad + bc) * 2^16 + bd * 2^32
+ // Also note that below, a * d + ((a * c) >> 16) is guaranteed not to overflow, because:
+ // a <= 0xffff, d <= 0xffff, ((a * c) >> 16) <= 0xffff and 0xffff * 0xffff + 0xffff = 0xffff0000
+ emu->addEmulatedFunction(BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ "void umulExtended_emu(uint x, uint y, out uint msb, out uint lsb)\n"
+ "{\n"
+ " lsb = x * y;\n"
+ " uint a = (x & 0xffffu);\n"
+ " uint b = (x >> 16);\n"
+ " uint c = (y & 0xffffu);\n"
+ " uint d = (y >> 16);\n"
+ " uint ad = a * d + ((a * c) >> 16);\n"
+ " uint bc = b * c;\n"
+ " uint carry = uint(ad > (0xffffffffu - bc));\n"
+ " msb = ((ad + bc) >> 16) + (carry << 16) + b * d;\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ BuiltInId::umulExtended_UInt2_UInt2_UInt2_UInt2,
+ "void umulExtended_emu(uint2 x, uint2 y, out uint2 msb, out uint2 lsb)\n"
+ "{\n"
+ " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ BuiltInId::umulExtended_UInt3_UInt3_UInt3_UInt3,
+ "void umulExtended_emu(uint3 x, uint3 y, out uint3 msb, out uint3 lsb)\n"
+ "{\n"
+ " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ " umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ BuiltInId::umulExtended_UInt4_UInt4_UInt4_UInt4,
+ "void umulExtended_emu(uint4 x, uint4 y, out uint4 msb, out uint4 lsb)\n"
+ "{\n"
+ " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ " umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
+ " umulExtended_emu(x.w, y.w, msb.w, lsb.w);\n"
+ "}\n");
+
+ // The imul emulation does two's complement negation on the lsb and msb manually in case the
+ // result needs to be negative.
+ // TODO(oetuaho): Note that this code doesn't take one edge case into account, where x or y is
+ // -2^31. abs(-2^31) is undefined.
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ BuiltInId::imulExtended_Int1_Int1_Int1_Int1,
+ "void imulExtended_emu(int x, int y, out int msb, out int lsb)\n"
+ "{\n"
+ " uint unsignedMsb;\n"
+ " uint unsignedLsb;\n"
+ " bool negative = (x < 0) != (y < 0);\n"
+ " umulExtended_emu(uint(abs(x)), uint(abs(y)), unsignedMsb, unsignedLsb);\n"
+ " lsb = asint(unsignedLsb);\n"
+ " msb = asint(unsignedMsb);\n"
+ " if (negative)\n"
+ " {\n"
+ " lsb = ~lsb;\n"
+ " msb = ~msb;\n"
+ " if (lsb == 0xffffffff)\n"
+ " {\n"
+ " lsb = 0;\n"
+ " msb += 1;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " lsb += 1;\n"
+ " }\n"
+ " }\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int2_Int2_Int2_Int2,
+ "void imulExtended_emu(int2 x, int2 y, out int2 msb, out int2 lsb)\n"
+ "{\n"
+ " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int3_Int3_Int3_Int3,
+ "void imulExtended_emu(int3 x, int3 y, out int3 msb, out int3 lsb)\n"
+ "{\n"
+ " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ " imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int4_Int4_Int4_Int4,
+ "void imulExtended_emu(int4 x, int4 y, out int4 msb, out int4 lsb)\n"
+ "{\n"
+ " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ " imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
+ " imulExtended_emu(x.w, y.w, msb.w, lsb.w);\n"
+ "}\n");
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h
new file mode 100644
index 0000000000..e5c6070fe6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
+#define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+namespace sh
+{
+
+class BuiltInFunctionEmulator;
+
+void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu);
+
+//
+// This works around isnan() bug on some Intel drivers.
+//
+void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
+ int targetGLSLVersion);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.cpp
new file mode 100644
index 0000000000..6409f85c3c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.cpp
@@ -0,0 +1,109 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/BuiltinsWorkaroundGLSL.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr const ImmutableString kGlInstanceIDString("gl_InstanceID");
+constexpr const ImmutableString kGlVertexIDString("gl_VertexID");
+
+class TBuiltinsWorkaroundGLSL : public TIntermTraverser
+{
+ public:
+ TBuiltinsWorkaroundGLSL(TSymbolTable *symbolTable, const ShCompileOptions &options);
+
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+
+ private:
+ void ensureVersionIsAtLeast(int version);
+
+ const ShCompileOptions &mCompileOptions;
+
+ bool isBaseInstanceDeclared = false;
+};
+
+TBuiltinsWorkaroundGLSL::TBuiltinsWorkaroundGLSL(TSymbolTable *symbolTable,
+ const ShCompileOptions &options)
+ : TIntermTraverser(true, false, false, symbolTable), mCompileOptions(options)
+{}
+
+void TBuiltinsWorkaroundGLSL::visitSymbol(TIntermSymbol *node)
+{
+ if (node->variable().symbolType() == SymbolType::BuiltIn)
+ {
+ if (node->getName() == kGlInstanceIDString)
+ {
+ TIntermSymbol *instanceIndexRef =
+ new TIntermSymbol(BuiltInVariable::gl_InstanceIndex());
+
+ if (isBaseInstanceDeclared)
+ {
+ TIntermSymbol *baseInstanceRef =
+ new TIntermSymbol(BuiltInVariable::angle_BaseInstance());
+
+ TIntermBinary *subBaseInstance =
+ new TIntermBinary(EOpSub, instanceIndexRef, baseInstanceRef);
+ queueReplacement(subBaseInstance, OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ queueReplacement(instanceIndexRef, OriginalNode::IS_DROPPED);
+ }
+ }
+ else if (node->getName() == kGlVertexIDString)
+ {
+ TIntermSymbol *vertexIndexRef = new TIntermSymbol(BuiltInVariable::gl_VertexIndex());
+ queueReplacement(vertexIndexRef, OriginalNode::IS_DROPPED);
+ }
+ }
+}
+
+bool TBuiltinsWorkaroundGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+ ASSERT(!sequence.empty());
+
+ for (TIntermNode *variableNode : sequence)
+ {
+ TIntermSymbol *variable = variableNode->getAsSymbolNode();
+ if (variable && variable->variable().symbolType() == SymbolType::BuiltIn)
+ {
+ if (variable->getName() == "angle_BaseInstance")
+ {
+ isBaseInstanceDeclared = true;
+ }
+ }
+ }
+ return true;
+}
+
+} // anonymous namespace
+
+[[nodiscard]] bool ShaderBuiltinsWorkaround(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions)
+{
+ TBuiltinsWorkaroundGLSL builtins(symbolTable, compileOptions);
+ root->traverse(&builtins);
+ if (!builtins.updateTree(compiler, root))
+ {
+ return false;
+ }
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.h b/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.h
new file mode 100644
index 0000000000..e49273dae9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_BUILTINSWORKAROUNDGLSL_H_
+#define COMPILER_TRANSLATOR_BUILTINSWORKAROUNDGLSL_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+#include "compiler/translator/Pragma.h"
+
+namespace sh
+{
+
+[[nodiscard]] bool ShaderBuiltinsWorkaround(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_BUILTINSWORKAROUNDGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/CallDAG.cpp b/gfx/angle/checkout/src/compiler/translator/CallDAG.cpp
new file mode 100644
index 0000000000..5d47518eba
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/CallDAG.cpp
@@ -0,0 +1,316 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// CallDAG.h: Implements a call graph DAG of functions to be re-used accross
+// analyses, allows to efficiently traverse the functions in topological
+// order.
+
+#include "compiler/translator/CallDAG.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+// The CallDAGCreator does all the processing required to create the CallDAG
+// structure so that the latter contains only the necessary variables.
+class CallDAG::CallDAGCreator : public TIntermTraverser
+{
+ public:
+ CallDAGCreator(TDiagnostics *diagnostics)
+ : TIntermTraverser(true, false, false),
+ mDiagnostics(diagnostics),
+ mCurrentFunction(nullptr),
+ mCurrentIndex(0)
+ {}
+
+ InitResult assignIndices()
+ {
+ int skipped = 0;
+ for (auto &it : mFunctions)
+ {
+ // Skip unimplemented functions
+ if (it.second.definitionNode)
+ {
+ InitResult result = assignIndicesInternal(&it.second);
+ if (result != INITDAG_SUCCESS)
+ {
+ return result;
+ }
+ }
+ else
+ {
+ skipped++;
+ }
+ }
+
+ ASSERT(mFunctions.size() == mCurrentIndex + skipped);
+ return INITDAG_SUCCESS;
+ }
+
+ void fillDataStructures(std::vector<Record> *records, std::map<int, int> *idToIndex)
+ {
+ ASSERT(records->empty());
+ ASSERT(idToIndex->empty());
+
+ records->resize(mCurrentIndex);
+
+ for (auto &it : mFunctions)
+ {
+ CreatorFunctionData &data = it.second;
+ // Skip unimplemented functions
+ if (!data.definitionNode)
+ {
+ continue;
+ }
+ ASSERT(data.index < records->size());
+ Record &record = (*records)[data.index];
+
+ record.node = data.definitionNode;
+
+ record.callees.reserve(data.callees.size());
+ for (auto &callee : data.callees)
+ {
+ record.callees.push_back(static_cast<int>(callee->index));
+ }
+
+ (*idToIndex)[it.first] = static_cast<int>(data.index);
+ }
+ }
+
+ private:
+ struct CreatorFunctionData
+ {
+ CreatorFunctionData()
+ : definitionNode(nullptr), name(""), index(0), indexAssigned(false), visiting(false)
+ {}
+
+ std::set<CreatorFunctionData *> callees;
+ TIntermFunctionDefinition *definitionNode;
+ ImmutableString name;
+ size_t index;
+ bool indexAssigned;
+ bool visiting;
+ };
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ // Create the record if need be and remember the definition node.
+ mCurrentFunction = &mFunctions[node->getFunction()->uniqueId().get()];
+ // Name will be overwritten here. If we've already traversed the prototype of this function,
+ // it should have had the same name.
+ ASSERT(mCurrentFunction->name == "" ||
+ mCurrentFunction->name == node->getFunction()->name());
+ mCurrentFunction->name = node->getFunction()->name();
+ mCurrentFunction->definitionNode = node;
+
+ node->getBody()->traverse(this);
+ mCurrentFunction = nullptr;
+ return false;
+ }
+
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override
+ {
+ ASSERT(mCurrentFunction == nullptr);
+
+ // Function declaration, create an empty record.
+ auto &record = mFunctions[node->getFunction()->uniqueId().get()];
+ record.name = node->getFunction()->name();
+ }
+
+ // Track functions called from another function.
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (node->getOp() == EOpCallFunctionInAST)
+ {
+ // Function call, add the callees
+ auto it = mFunctions.find(node->getFunction()->uniqueId().get());
+ ASSERT(it != mFunctions.end());
+
+ // We might be traversing the initializer of a global variable. Even though function
+ // calls in global scope are forbidden by the parser, some subsequent AST
+ // transformations can add them to emulate particular features.
+ if (mCurrentFunction)
+ {
+ mCurrentFunction->callees.insert(&it->second);
+ }
+ }
+ return true;
+ }
+
+ // Recursively assigns indices to a sub DAG
+ InitResult assignIndicesInternal(CreatorFunctionData *root)
+ {
+ // Iterative implementation of the index assignment algorithm. A recursive version
+ // would be prettier but since the CallDAG creation runs before the limiting of the
+ // call depth, we might get stack overflows (computation of the call depth uses the
+ // CallDAG).
+
+ ASSERT(root);
+
+ if (root->indexAssigned)
+ {
+ return INITDAG_SUCCESS;
+ }
+
+ // If we didn't have to detect recursion, functionsToProcess could be a simple queue
+ // in which we add the function being processed's callees. However in order to detect
+ // recursion we need to know which functions we are currently visiting. For that reason
+ // functionsToProcess will look like a concatenation of segments of the form
+ // [F visiting = true, subset of F callees with visiting = false] and the following
+ // segment (if any) will be start with a callee of F.
+ // This way we can remember when we started visiting a function, to put visiting back
+ // to false.
+ TVector<CreatorFunctionData *> functionsToProcess;
+ functionsToProcess.push_back(root);
+
+ InitResult result = INITDAG_SUCCESS;
+
+ std::stringstream errorStream = sh::InitializeStream<std::stringstream>();
+
+ while (!functionsToProcess.empty())
+ {
+ CreatorFunctionData *function = functionsToProcess.back();
+
+ if (function->visiting)
+ {
+ function->visiting = false;
+ function->index = mCurrentIndex++;
+ function->indexAssigned = true;
+
+ functionsToProcess.pop_back();
+ continue;
+ }
+
+ if (!function->definitionNode)
+ {
+ errorStream << "Undefined function '" << function->name
+ << "()' used in the following call chain:";
+ result = INITDAG_UNDEFINED;
+ break;
+ }
+
+ if (function->indexAssigned)
+ {
+ functionsToProcess.pop_back();
+ continue;
+ }
+
+ function->visiting = true;
+
+ for (auto callee : function->callees)
+ {
+ functionsToProcess.push_back(callee);
+
+ // Check if the callee is already being visited after pushing it so that it appears
+ // in the chain printed in the info log.
+ if (callee->visiting)
+ {
+ errorStream << "Recursive function call in the following call chain:";
+ result = INITDAG_RECURSION;
+ break;
+ }
+ }
+
+ if (result != INITDAG_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ // The call chain is made of the function we were visiting when the error was detected.
+ if (result != INITDAG_SUCCESS)
+ {
+ bool first = true;
+ for (auto function : functionsToProcess)
+ {
+ if (function->visiting)
+ {
+ if (!first)
+ {
+ errorStream << " -> ";
+ }
+ errorStream << function->name << ")";
+ first = false;
+ }
+ }
+ if (mDiagnostics)
+ {
+ std::string errorStr = errorStream.str();
+ mDiagnostics->globalError(errorStr.c_str());
+ }
+ }
+
+ return result;
+ }
+
+ TDiagnostics *mDiagnostics;
+
+ std::map<int, CreatorFunctionData> mFunctions;
+ CreatorFunctionData *mCurrentFunction;
+ size_t mCurrentIndex;
+};
+
+// CallDAG
+
+CallDAG::CallDAG() {}
+
+CallDAG::~CallDAG() {}
+
+const size_t CallDAG::InvalidIndex = std::numeric_limits<size_t>::max();
+
+size_t CallDAG::findIndex(const TSymbolUniqueId &id) const
+{
+ auto it = mFunctionIdToIndex.find(id.get());
+
+ if (it == mFunctionIdToIndex.end())
+ {
+ return InvalidIndex;
+ }
+ else
+ {
+ return it->second;
+ }
+}
+
+const CallDAG::Record &CallDAG::getRecordFromIndex(size_t index) const
+{
+ ASSERT(index != InvalidIndex && index < mRecords.size());
+ return mRecords[index];
+}
+
+size_t CallDAG::size() const
+{
+ return mRecords.size();
+}
+
+void CallDAG::clear()
+{
+ mRecords.clear();
+ mFunctionIdToIndex.clear();
+}
+
+CallDAG::InitResult CallDAG::init(TIntermNode *root, TDiagnostics *diagnostics)
+{
+ CallDAGCreator creator(diagnostics);
+
+ // Creates the mapping of functions to callees
+ root->traverse(&creator);
+
+ // Does the topological sort and detects recursions
+ InitResult result = creator.assignIndices();
+ if (result != INITDAG_SUCCESS)
+ {
+ return result;
+ }
+
+ creator.fillDataStructures(&mRecords, &mFunctionIdToIndex);
+ return INITDAG_SUCCESS;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/CallDAG.h b/gfx/angle/checkout/src/compiler/translator/CallDAG.h
new file mode 100644
index 0000000000..7e80f2e855
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/CallDAG.h
@@ -0,0 +1,77 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// CallDAG.h: Defines a call graph DAG of functions to be re-used accross
+// analyses, allows to efficiently traverse the functions in topological
+// order.
+
+#ifndef COMPILER_TRANSLATOR_CALLDAG_H_
+#define COMPILER_TRANSLATOR_CALLDAG_H_
+
+#include <map>
+
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+// The translator needs to analyze the the graph of the function calls
+// to run checks and analyses; since in GLSL recursion is not allowed
+// that graph is a DAG.
+// This class is used to precompute that function call DAG so that it
+// can be reused by multiple analyses.
+//
+// It stores a vector of function records, with one record per defined function.
+// Records are accessed by index but a function symbol id can be converted
+// to the index of the corresponding record. The records contain the AST node
+// of the function definition and the indices of the function's callees.
+//
+// In addition, records are in reverse topological order: a function F being
+// called by a function G will have index index(F) < index(G), that way
+// depth-first analysis becomes analysis in the order of indices.
+
+class CallDAG : angle::NonCopyable
+{
+ public:
+ CallDAG();
+ ~CallDAG();
+
+ struct Record
+ {
+ TIntermFunctionDefinition *node; // Guaranteed to be non-null.
+ std::vector<int> callees;
+ };
+
+ enum InitResult
+ {
+ INITDAG_SUCCESS,
+ INITDAG_RECURSION,
+ INITDAG_UNDEFINED,
+ };
+
+ // Returns INITDAG_SUCCESS if it was able to create the DAG, otherwise prints
+ // the initialization error in diagnostics, if present.
+ InitResult init(TIntermNode *root, TDiagnostics *diagnostics);
+
+ // Returns InvalidIndex if the function wasn't found
+ size_t findIndex(const TSymbolUniqueId &id) const;
+
+ const Record &getRecordFromIndex(size_t index) const;
+ size_t size() const;
+ void clear();
+
+ const static size_t InvalidIndex;
+
+ private:
+ std::vector<Record> mRecords;
+ std::map<int, int> mFunctionIdToIndex;
+
+ class CallDAGCreator;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_CALLDAG_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/CodeGen.cpp b/gfx/angle/checkout/src/compiler/translator/CodeGen.cpp
new file mode 100644
index 0000000000..497ef881e2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/CodeGen.cpp
@@ -0,0 +1,96 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifdef ANGLE_ENABLE_ESSL
+# include "compiler/translator/TranslatorESSL.h"
+#endif // ANGLE_ENABLE_ESSL
+
+#ifdef ANGLE_ENABLE_GLSL
+# include "compiler/translator/TranslatorGLSL.h"
+#endif // ANGLE_ENABLE_GLSL
+
+#ifdef ANGLE_ENABLE_HLSL
+# include "compiler/translator/TranslatorHLSL.h"
+#endif // ANGLE_ENABLE_HLSL
+
+#ifdef ANGLE_ENABLE_VULKAN
+# include "compiler/translator/TranslatorVulkan.h"
+#endif // ANGLE_ENABLE_VULKAN
+
+#ifdef ANGLE_ENABLE_METAL
+# include "compiler/translator/TranslatorMetalDirect.h"
+#endif // ANGLE_ENABLE_METAL
+
+#ifdef ANGLE_ENABLE_METAL_SPIRV
+# include "compiler/translator/TranslatorMetal.h"
+#endif // ANGLE_ENABLE_METAL_SPIRV
+
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+//
+// This function must be provided to create the actual
+// compile object used by higher level code. It returns
+// a subclass of TCompiler.
+//
+TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
+{
+#ifdef ANGLE_ENABLE_ESSL
+ if (IsOutputESSL(output))
+ {
+ return new TranslatorESSL(type, spec);
+ }
+#endif // ANGLE_ENABLE_ESSL
+
+#ifdef ANGLE_ENABLE_GLSL
+ if (IsOutputGLSL(output))
+ {
+ return new TranslatorGLSL(type, spec, output);
+ }
+#endif // ANGLE_ENABLE_GLSL
+
+#ifdef ANGLE_ENABLE_HLSL
+ if (IsOutputHLSL(output))
+ {
+ return new TranslatorHLSL(type, spec, output);
+ }
+#endif // ANGLE_ENABLE_HLSL
+
+#ifdef ANGLE_ENABLE_VULKAN
+ if (IsOutputVulkan(output))
+ {
+ return new TranslatorVulkan(type, spec);
+ }
+#endif // ANGLE_ENABLE_VULKAN
+
+#ifdef ANGLE_ENABLE_METAL_SPIRV
+ if (IsOutputMetal(output))
+ {
+ return new TranslatorMetal(type, spec);
+ }
+#endif
+#ifdef ANGLE_ENABLE_METAL
+ if (IsOutputMetalDirect(output))
+ {
+ return new TranslatorMetalDirect(type, spec, output);
+ }
+#endif // ANGLE_ENABLE_METAL
+
+ // Unsupported compiler or unknown format. Return nullptr per the sh::ConstructCompiler API.
+ return nullptr;
+}
+
+//
+// Delete the compiler made by ConstructCompiler
+//
+void DeleteCompiler(TCompiler *compiler)
+{
+ SafeDelete(compiler);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp b/gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp
new file mode 100644
index 0000000000..d6c58bebcb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp
@@ -0,0 +1,1288 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// CollectVariables.cpp: Collect lists of shader interface variables based on the AST.
+
+#include "compiler/translator/CollectVariables.h"
+
+#include "angle_gl.h"
+#include "common/utilities.h"
+#include "compiler/translator/HashNames.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
+{
+ switch (blockStorage)
+ {
+ case EbsPacked:
+ return BLOCKLAYOUT_PACKED;
+ case EbsShared:
+ return BLOCKLAYOUT_SHARED;
+ case EbsStd140:
+ return BLOCKLAYOUT_STD140;
+ case EbsStd430:
+ return BLOCKLAYOUT_STD430;
+ default:
+ UNREACHABLE();
+ return BLOCKLAYOUT_SHARED;
+ }
+}
+
+BlockType GetBlockType(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqUniform:
+ return BlockType::BLOCK_UNIFORM;
+ case EvqBuffer:
+ return BlockType::BLOCK_BUFFER;
+ default:
+ UNREACHABLE();
+ return BlockType::BLOCK_UNIFORM;
+ }
+}
+
+template <class VarT>
+VarT *FindVariable(const ImmutableString &name, std::vector<VarT> *infoList)
+{
+ // TODO(zmo): optimize this function.
+ for (size_t ii = 0; ii < infoList->size(); ++ii)
+ {
+ if (name == (*infoList)[ii].name)
+ return &((*infoList)[ii]);
+ }
+
+ return nullptr;
+}
+
+void MarkActive(ShaderVariable *variable)
+{
+ if (!variable->active)
+ {
+ if (variable->isStruct())
+ {
+ // Conservatively assume all fields are statically used as well.
+ for (auto &field : variable->fields)
+ {
+ MarkActive(&field);
+ }
+ }
+ variable->staticUse = true;
+ variable->active = true;
+ }
+}
+
+ShaderVariable *FindVariableInInterfaceBlock(const ImmutableString &name,
+ const TInterfaceBlock *interfaceBlock,
+ std::vector<InterfaceBlock> *infoList)
+{
+ ASSERT(interfaceBlock);
+ InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), infoList);
+ ASSERT(namedBlock);
+
+ // Set static use on the parent interface block here
+ namedBlock->staticUse = true;
+ namedBlock->active = true;
+ return FindVariable(name, &namedBlock->fields);
+}
+
+ShaderVariable *FindShaderIOBlockVariable(const ImmutableString &blockName,
+ std::vector<ShaderVariable> *infoList)
+{
+ for (size_t index = 0; index < infoList->size(); ++index)
+ {
+ if (blockName == (*infoList)[index].structOrBlockName)
+ return &(*infoList)[index];
+ }
+
+ return nullptr;
+}
+
+// Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs,
+// shared data and interface blocks.
+class CollectVariablesTraverser : public TIntermTraverser
+{
+ public:
+ CollectVariablesTraverser(std::vector<ShaderVariable> *attribs,
+ std::vector<ShaderVariable> *outputVariables,
+ std::vector<ShaderVariable> *uniforms,
+ std::vector<ShaderVariable> *inputVaryings,
+ std::vector<ShaderVariable> *outputVaryings,
+ std::vector<ShaderVariable> *sharedVariables,
+ std::vector<InterfaceBlock> *uniformBlocks,
+ std::vector<InterfaceBlock> *shaderStorageBlocks,
+ ShHashFunction64 hashFunction,
+ TSymbolTable *symbolTable,
+ GLenum shaderType,
+ const TExtensionBehavior &extensionBehavior,
+ const ShBuiltInResources &resources,
+ int tessControlShaderOutputVertices);
+
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override;
+ void visitSymbol(TIntermSymbol *symbol) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
+
+ private:
+ std::string getMappedName(const TSymbol *symbol) const;
+
+ void setFieldOrVariableProperties(const TType &type,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ ShaderVariable *variableOut) const;
+ void setFieldProperties(const TType &type,
+ const ImmutableString &name,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ SymbolType symbolType,
+ ShaderVariable *variableOut) const;
+ void setCommonVariableProperties(const TType &type,
+ const TVariable &variable,
+ ShaderVariable *variableOut) const;
+
+ ShaderVariable recordAttribute(const TIntermSymbol &variable) const;
+ ShaderVariable recordOutputVariable(const TIntermSymbol &variable) const;
+ ShaderVariable recordVarying(const TIntermSymbol &variable) const;
+ void recordInterfaceBlock(const char *instanceName,
+ const TType &interfaceBlockType,
+ InterfaceBlock *interfaceBlock) const;
+ ShaderVariable recordUniform(const TIntermSymbol &variable) const;
+
+ void setBuiltInInfoFromSymbol(const TVariable &variable, ShaderVariable *info);
+
+ void recordBuiltInVaryingUsed(const TVariable &variable,
+ bool *addedFlag,
+ std::vector<ShaderVariable> *varyings);
+ void recordBuiltInFragmentOutputUsed(const TVariable &variable, bool *addedFlag);
+ void recordBuiltInAttributeUsed(const TVariable &variable, bool *addedFlag);
+ InterfaceBlock *findNamedInterfaceBlock(const ImmutableString &name) const;
+
+ std::vector<ShaderVariable> *mAttribs;
+ std::vector<ShaderVariable> *mOutputVariables;
+ std::vector<ShaderVariable> *mUniforms;
+ std::vector<ShaderVariable> *mInputVaryings;
+ std::vector<ShaderVariable> *mOutputVaryings;
+ std::vector<ShaderVariable> *mSharedVariables;
+ std::vector<InterfaceBlock> *mUniformBlocks;
+ std::vector<InterfaceBlock> *mShaderStorageBlocks;
+
+ std::map<std::string, ShaderVariable *> mInterfaceBlockFields;
+
+ // Shader uniforms
+ bool mDepthRangeAdded;
+ bool mNumSamplesAdded;
+
+ // Compute Shader builtins
+ bool mNumWorkGroupsAdded;
+ bool mWorkGroupIDAdded;
+ bool mLocalInvocationIDAdded;
+ bool mGlobalInvocationIDAdded;
+ bool mLocalInvocationIndexAdded;
+
+ // Vertex Shader builtins
+ bool mInstanceIDAdded;
+ bool mVertexIDAdded;
+ bool mPointSizeAdded;
+ bool mDrawIDAdded;
+
+ // Vertex Shader and Geometry Shader builtins
+ bool mPositionAdded;
+ bool mClipDistanceAdded;
+ bool mCullDistanceAdded;
+
+ // Fragment Shader builtins
+ bool mPointCoordAdded;
+ bool mFrontFacingAdded;
+ bool mHelperInvocationAdded;
+ bool mFragCoordAdded;
+ bool mLastFragDataAdded;
+ bool mFragColorAdded;
+ bool mFragDataAdded;
+ bool mFragDepthAdded;
+ bool mSecondaryFragColorEXTAdded;
+ bool mSecondaryFragDataEXTAdded;
+ bool mSampleIDAdded;
+ bool mSamplePositionAdded;
+ bool mSampleMaskAdded;
+ bool mSampleMaskInAdded;
+
+ // Geometry and Tessellation Shader builtins
+ bool mPerVertexInAdded;
+ bool mPerVertexOutAdded;
+
+ // Geometry Shader builtins
+ bool mPrimitiveIDInAdded;
+ bool mInvocationIDAdded;
+
+ // Geometry Shader and Fragment Shader builtins
+ bool mPrimitiveIDAdded;
+ bool mLayerAdded;
+
+ // Shared memory variables
+ bool mSharedVariableAdded;
+
+ // Tessellation Shader builtins
+ bool mPatchVerticesInAdded;
+ bool mTessLevelOuterAdded;
+ bool mTessLevelInnerAdded;
+ bool mBoundingBoxAdded;
+ bool mTessCoordAdded;
+ const int mTessControlShaderOutputVertices;
+
+ ShHashFunction64 mHashFunction;
+
+ GLenum mShaderType;
+ const TExtensionBehavior &mExtensionBehavior;
+ const ShBuiltInResources &mResources;
+};
+
+CollectVariablesTraverser::CollectVariablesTraverser(
+ std::vector<sh::ShaderVariable> *attribs,
+ std::vector<sh::ShaderVariable> *outputVariables,
+ std::vector<sh::ShaderVariable> *uniforms,
+ std::vector<sh::ShaderVariable> *inputVaryings,
+ std::vector<sh::ShaderVariable> *outputVaryings,
+ std::vector<sh::ShaderVariable> *sharedVariables,
+ std::vector<sh::InterfaceBlock> *uniformBlocks,
+ std::vector<sh::InterfaceBlock> *shaderStorageBlocks,
+ ShHashFunction64 hashFunction,
+ TSymbolTable *symbolTable,
+ GLenum shaderType,
+ const TExtensionBehavior &extensionBehavior,
+ const ShBuiltInResources &resources,
+ int tessControlShaderOutputVertices)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mAttribs(attribs),
+ mOutputVariables(outputVariables),
+ mUniforms(uniforms),
+ mInputVaryings(inputVaryings),
+ mOutputVaryings(outputVaryings),
+ mSharedVariables(sharedVariables),
+ mUniformBlocks(uniformBlocks),
+ mShaderStorageBlocks(shaderStorageBlocks),
+ mDepthRangeAdded(false),
+ mNumSamplesAdded(false),
+ mNumWorkGroupsAdded(false),
+ mWorkGroupIDAdded(false),
+ mLocalInvocationIDAdded(false),
+ mGlobalInvocationIDAdded(false),
+ mLocalInvocationIndexAdded(false),
+ mInstanceIDAdded(false),
+ mVertexIDAdded(false),
+ mPointSizeAdded(false),
+ mDrawIDAdded(false),
+ mPositionAdded(false),
+ mClipDistanceAdded(false),
+ mCullDistanceAdded(false),
+ mPointCoordAdded(false),
+ mFrontFacingAdded(false),
+ mHelperInvocationAdded(false),
+ mFragCoordAdded(false),
+ mLastFragDataAdded(false),
+ mFragColorAdded(false),
+ mFragDataAdded(false),
+ mFragDepthAdded(false),
+ mSecondaryFragColorEXTAdded(false),
+ mSecondaryFragDataEXTAdded(false),
+ mSampleIDAdded(false),
+ mSamplePositionAdded(false),
+ mSampleMaskAdded(false),
+ mSampleMaskInAdded(false),
+ mPerVertexInAdded(false),
+ mPerVertexOutAdded(false),
+ mPrimitiveIDInAdded(false),
+ mInvocationIDAdded(false),
+ mPrimitiveIDAdded(false),
+ mLayerAdded(false),
+ mSharedVariableAdded(false),
+ mPatchVerticesInAdded(false),
+ mTessLevelOuterAdded(false),
+ mTessLevelInnerAdded(false),
+ mBoundingBoxAdded(false),
+ mTessCoordAdded(false),
+ mTessControlShaderOutputVertices(tessControlShaderOutputVertices),
+ mHashFunction(hashFunction),
+ mShaderType(shaderType),
+ mExtensionBehavior(extensionBehavior),
+ mResources(resources)
+{}
+
+std::string CollectVariablesTraverser::getMappedName(const TSymbol *symbol) const
+{
+ return HashName(symbol, mHashFunction, nullptr).data();
+}
+
+void CollectVariablesTraverser::setBuiltInInfoFromSymbol(const TVariable &variable,
+ ShaderVariable *info)
+{
+ const TType &type = variable.getType();
+
+ info->name = variable.name().data();
+ info->mappedName = variable.name().data();
+
+ bool isShaderIOBlock =
+ IsShaderIoBlock(type.getQualifier()) && type.getInterfaceBlock() != nullptr;
+ bool isPatch = type.getQualifier() == EvqTessLevelInner ||
+ type.getQualifier() == EvqTessLevelOuter ||
+ type.getQualifier() == EvqBoundingBox;
+
+ setFieldOrVariableProperties(type, true, isShaderIOBlock, isPatch, info);
+}
+
+void CollectVariablesTraverser::recordBuiltInVaryingUsed(const TVariable &variable,
+ bool *addedFlag,
+ std::vector<ShaderVariable> *varyings)
+{
+ ASSERT(varyings);
+ if (!(*addedFlag))
+ {
+ ShaderVariable info;
+ setBuiltInInfoFromSymbol(variable, &info);
+ info.active = true;
+ info.isInvariant = mSymbolTable->isVaryingInvariant(variable);
+
+ varyings->push_back(info);
+ (*addedFlag) = true;
+ }
+}
+
+void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const TVariable &variable,
+ bool *addedFlag)
+{
+ if (!(*addedFlag))
+ {
+ ShaderVariable info;
+ setBuiltInInfoFromSymbol(variable, &info);
+ info.active = true;
+ mOutputVariables->push_back(info);
+ (*addedFlag) = true;
+ }
+}
+
+void CollectVariablesTraverser::recordBuiltInAttributeUsed(const TVariable &variable,
+ bool *addedFlag)
+{
+ if (!(*addedFlag))
+ {
+ ShaderVariable info;
+ setBuiltInInfoFromSymbol(variable, &info);
+ info.active = true;
+ info.location = -1;
+ mAttribs->push_back(info);
+ (*addedFlag) = true;
+ }
+}
+
+bool CollectVariablesTraverser::visitGlobalQualifierDeclaration(
+ Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+{
+ // We should not mark variables as active just based on an invariant/precise declaration, so we
+ // don't traverse the symbols declared invariant.
+ return false;
+}
+
+// We want to check whether a uniform/varying is active because we need to skip updating inactive
+// ones. We also only count the active ones in packing computing. Also, gl_FragCoord, gl_PointCoord,
+// and gl_FrontFacing count toward varying counting if they are active in a fragment shader.
+void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
+{
+ ASSERT(symbol != nullptr);
+
+ if (symbol->variable().symbolType() == SymbolType::AngleInternal ||
+ symbol->variable().symbolType() == SymbolType::Empty)
+ {
+ // Internal variables or nameless variables are not collected.
+ return;
+ }
+
+ ShaderVariable *var = nullptr;
+
+ const ImmutableString &symbolName = symbol->getName();
+
+ // Check the qualifier from the variable, not from the symbol node. The node may have a
+ // different qualifier if it's the result of a folded ternary node.
+ TQualifier qualifier = symbol->variable().getType().getQualifier();
+ const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
+
+ if (IsVaryingIn(qualifier))
+ {
+ if (interfaceBlock)
+ {
+ var = FindShaderIOBlockVariable(interfaceBlock->name(), mInputVaryings);
+ }
+ else
+ {
+ var = FindVariable(symbolName, mInputVaryings);
+ }
+ }
+ else if (IsVaryingOut(qualifier))
+ {
+ if (interfaceBlock)
+ {
+ var = FindShaderIOBlockVariable(interfaceBlock->name(), mOutputVaryings);
+ }
+ else
+ {
+ var = FindVariable(symbolName, mOutputVaryings);
+ }
+ }
+ else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
+ {
+ UNREACHABLE();
+ }
+ else if (symbolName == "gl_DepthRange")
+ {
+ ASSERT(qualifier == EvqUniform);
+
+ if (!mDepthRangeAdded)
+ {
+ ShaderVariable info;
+ const char kName[] = "gl_DepthRange";
+ info.name = kName;
+ info.mappedName = kName;
+ info.type = GL_NONE;
+ info.precision = GL_NONE;
+ info.staticUse = true;
+ info.active = true;
+
+ ShaderVariable nearInfo(GL_FLOAT);
+ const char kNearName[] = "near";
+ nearInfo.name = kNearName;
+ nearInfo.mappedName = kNearName;
+ nearInfo.precision = GL_HIGH_FLOAT;
+ nearInfo.staticUse = true;
+ nearInfo.active = true;
+
+ ShaderVariable farInfo(GL_FLOAT);
+ const char kFarName[] = "far";
+ farInfo.name = kFarName;
+ farInfo.mappedName = kFarName;
+ farInfo.precision = GL_HIGH_FLOAT;
+ farInfo.staticUse = true;
+ farInfo.active = true;
+
+ ShaderVariable diffInfo(GL_FLOAT);
+ const char kDiffName[] = "diff";
+ diffInfo.name = kDiffName;
+ diffInfo.mappedName = kDiffName;
+ diffInfo.precision = GL_HIGH_FLOAT;
+ diffInfo.staticUse = true;
+ diffInfo.active = true;
+
+ info.fields.push_back(nearInfo);
+ info.fields.push_back(farInfo);
+ info.fields.push_back(diffInfo);
+
+ mUniforms->push_back(info);
+ mDepthRangeAdded = true;
+ }
+ }
+ else if (symbolName == "gl_NumSamples")
+ {
+ ASSERT(qualifier == EvqUniform);
+
+ if (!mNumSamplesAdded)
+ {
+ ShaderVariable info;
+ const char kName[] = "gl_NumSamples";
+ info.name = kName;
+ info.mappedName = kName;
+ info.type = GL_INT;
+ info.precision = GL_LOW_INT;
+ info.staticUse = true;
+ info.active = true;
+
+ mUniforms->push_back(info);
+ mNumSamplesAdded = true;
+ }
+ }
+ else
+ {
+ switch (qualifier)
+ {
+ case EvqAttribute:
+ case EvqVertexIn:
+ var = FindVariable(symbolName, mAttribs);
+ break;
+ case EvqFragmentOut:
+ case EvqFragmentInOut:
+ var = FindVariable(symbolName, mOutputVariables);
+ var->isFragmentInOut = qualifier == EvqFragmentInOut;
+ break;
+ case EvqUniform:
+ {
+ if (interfaceBlock)
+ {
+ var = FindVariableInInterfaceBlock(symbolName, interfaceBlock, mUniformBlocks);
+ }
+ else
+ {
+ var = FindVariable(symbolName, mUniforms);
+ }
+
+ // It's an internal error to reference an undefined user uniform
+ ASSERT(!gl::IsBuiltInName(symbolName.data()) || var);
+ }
+ break;
+ case EvqBuffer:
+ {
+ var =
+ FindVariableInInterfaceBlock(symbolName, interfaceBlock, mShaderStorageBlocks);
+ }
+ break;
+ case EvqFragCoord:
+ recordBuiltInVaryingUsed(symbol->variable(), &mFragCoordAdded, mInputVaryings);
+ return;
+ case EvqFrontFacing:
+ recordBuiltInVaryingUsed(symbol->variable(), &mFrontFacingAdded, mInputVaryings);
+ return;
+ case EvqHelperInvocation:
+ recordBuiltInVaryingUsed(symbol->variable(), &mHelperInvocationAdded,
+ mInputVaryings);
+ return;
+ case EvqPointCoord:
+ recordBuiltInVaryingUsed(symbol->variable(), &mPointCoordAdded, mInputVaryings);
+ return;
+ case EvqNumWorkGroups:
+ recordBuiltInAttributeUsed(symbol->variable(), &mNumWorkGroupsAdded);
+ return;
+ case EvqWorkGroupID:
+ recordBuiltInAttributeUsed(symbol->variable(), &mWorkGroupIDAdded);
+ return;
+ case EvqLocalInvocationID:
+ recordBuiltInAttributeUsed(symbol->variable(), &mLocalInvocationIDAdded);
+ return;
+ case EvqGlobalInvocationID:
+ recordBuiltInAttributeUsed(symbol->variable(), &mGlobalInvocationIDAdded);
+ return;
+ case EvqLocalInvocationIndex:
+ recordBuiltInAttributeUsed(symbol->variable(), &mLocalInvocationIndexAdded);
+ return;
+ case EvqInstanceID:
+ // Whenever the initializeBuiltinsForInstancedMultiview option is set,
+ // gl_InstanceID is added inside expressions to initialize ViewID_OVR and
+ // InstanceID. Note that gl_InstanceID is not added to the symbol table for ESSL1
+ // shaders.
+ recordBuiltInAttributeUsed(symbol->variable(), &mInstanceIDAdded);
+ return;
+ case EvqVertexID:
+ recordBuiltInAttributeUsed(symbol->variable(), &mVertexIDAdded);
+ return;
+ case EvqPosition:
+ recordBuiltInVaryingUsed(symbol->variable(), &mPositionAdded, mOutputVaryings);
+ return;
+ case EvqPointSize:
+ recordBuiltInVaryingUsed(symbol->variable(), &mPointSizeAdded, mOutputVaryings);
+ return;
+ case EvqDrawID:
+ recordBuiltInAttributeUsed(symbol->variable(), &mDrawIDAdded);
+ return;
+ case EvqLastFragData:
+ recordBuiltInVaryingUsed(symbol->variable(), &mLastFragDataAdded, mInputVaryings);
+ return;
+ case EvqFragColor:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragColorAdded);
+ return;
+ case EvqFragData:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragDataAdded);
+ return;
+ case EvqFragDepth:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragDepthAdded);
+ return;
+ case EvqSecondaryFragColorEXT:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mSecondaryFragColorEXTAdded);
+ return;
+ case EvqSecondaryFragDataEXT:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mSecondaryFragDataEXTAdded);
+ return;
+ case EvqInvocationID:
+ recordBuiltInVaryingUsed(symbol->variable(), &mInvocationIDAdded, mInputVaryings);
+ break;
+ case EvqPrimitiveIDIn:
+ recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDInAdded, mInputVaryings);
+ break;
+ case EvqPrimitiveID:
+ if (mShaderType == GL_GEOMETRY_SHADER_EXT)
+ {
+ recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDAdded,
+ mOutputVaryings);
+ }
+ else
+ {
+ ASSERT(mShaderType == GL_FRAGMENT_SHADER ||
+ mShaderType == GL_TESS_CONTROL_SHADER ||
+ mShaderType == GL_TESS_EVALUATION_SHADER);
+ recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDAdded,
+ mInputVaryings);
+ }
+ break;
+ case EvqLayerOut:
+ if (mShaderType == GL_GEOMETRY_SHADER_EXT)
+ {
+ recordBuiltInVaryingUsed(symbol->variable(), &mLayerAdded, mOutputVaryings);
+ }
+ else
+ {
+ ASSERT(mShaderType == GL_VERTEX_SHADER &&
+ (IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview2) ||
+ IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview)));
+ }
+ break;
+ case EvqLayerIn:
+ ASSERT(mShaderType == GL_FRAGMENT_SHADER);
+ recordBuiltInVaryingUsed(symbol->variable(), &mLayerAdded, mInputVaryings);
+ break;
+ case EvqShared:
+ if (mShaderType == GL_COMPUTE_SHADER)
+ {
+ recordBuiltInVaryingUsed(symbol->variable(), &mSharedVariableAdded,
+ mSharedVariables);
+ }
+ break;
+ case EvqClipDistance:
+ recordBuiltInVaryingUsed(
+ symbol->variable(), &mClipDistanceAdded,
+ mShaderType == GL_FRAGMENT_SHADER ? mInputVaryings : mOutputVaryings);
+ return;
+ case EvqCullDistance:
+ recordBuiltInVaryingUsed(
+ symbol->variable(), &mCullDistanceAdded,
+ mShaderType == GL_FRAGMENT_SHADER ? mInputVaryings : mOutputVaryings);
+ return;
+ case EvqSampleID:
+ recordBuiltInVaryingUsed(symbol->variable(), &mSampleIDAdded, mInputVaryings);
+ return;
+ case EvqSamplePosition:
+ recordBuiltInVaryingUsed(symbol->variable(), &mSamplePositionAdded, mInputVaryings);
+ return;
+ case EvqSampleMaskIn:
+ recordBuiltInVaryingUsed(symbol->variable(), &mSampleMaskInAdded, mInputVaryings);
+ return;
+ case EvqSampleMask:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mSampleMaskAdded);
+ return;
+ case EvqPatchVerticesIn:
+ recordBuiltInVaryingUsed(symbol->variable(), &mPatchVerticesInAdded,
+ mInputVaryings);
+ break;
+ case EvqTessCoord:
+ recordBuiltInVaryingUsed(symbol->variable(), &mTessCoordAdded, mInputVaryings);
+ break;
+ case EvqTessLevelOuter:
+ if (mShaderType == GL_TESS_CONTROL_SHADER)
+ {
+ recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelOuterAdded,
+ mOutputVaryings);
+ }
+ else
+ {
+ ASSERT(mShaderType == GL_TESS_EVALUATION_SHADER);
+ recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelOuterAdded,
+ mInputVaryings);
+ }
+ break;
+ case EvqTessLevelInner:
+ if (mShaderType == GL_TESS_CONTROL_SHADER)
+ {
+ recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelInnerAdded,
+ mOutputVaryings);
+ }
+ else
+ {
+ ASSERT(mShaderType == GL_TESS_EVALUATION_SHADER);
+ recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelInnerAdded,
+ mInputVaryings);
+ }
+ break;
+ case EvqBoundingBox:
+ recordBuiltInVaryingUsed(symbol->variable(), &mBoundingBoxAdded, mOutputVaryings);
+ break;
+ default:
+ break;
+ }
+ }
+ if (var)
+ {
+ MarkActive(var);
+ }
+}
+
+void CollectVariablesTraverser::setFieldOrVariableProperties(const TType &type,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ ShaderVariable *variableOut) const
+{
+ ASSERT(variableOut);
+
+ variableOut->staticUse = staticUse;
+ variableOut->isShaderIOBlock = isShaderIOBlock;
+ variableOut->isPatch = isPatch;
+
+ const TStructure *structure = type.getStruct();
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ if (structure)
+ {
+ // Structures use a NONE type that isn't exposed outside ANGLE.
+ variableOut->type = GL_NONE;
+ if (structure->symbolType() != SymbolType::Empty)
+ {
+ variableOut->structOrBlockName = structure->name().data();
+ }
+
+ const TFieldList &fields = structure->fields();
+
+ for (const TField *field : fields)
+ {
+ // Regardless of the variable type (uniform, in/out etc.) its fields are always plain
+ // ShaderVariable objects.
+ ShaderVariable fieldVariable;
+ setFieldProperties(*field->type(), field->name(), staticUse, isShaderIOBlock, isPatch,
+ field->symbolType(), &fieldVariable);
+ variableOut->fields.push_back(fieldVariable);
+ }
+ }
+ else if (interfaceBlock && isShaderIOBlock)
+ {
+ const bool isPerVertex = (interfaceBlock->name() == "gl_PerVertex");
+ variableOut->type = GL_NONE;
+ if (interfaceBlock->symbolType() != SymbolType::Empty)
+ {
+ variableOut->structOrBlockName = interfaceBlock->name().data();
+ variableOut->mappedStructOrBlockName =
+ isPerVertex ? interfaceBlock->name().data()
+ : HashName(interfaceBlock->name(), mHashFunction, nullptr).data();
+ }
+ const TFieldList &fields = interfaceBlock->fields();
+ for (const TField *field : fields)
+ {
+ ShaderVariable fieldVariable;
+
+ setFieldProperties(*field->type(), field->name(), staticUse, true, isPatch,
+ field->symbolType(), &fieldVariable);
+ fieldVariable.isShaderIOBlock = true;
+ variableOut->fields.push_back(fieldVariable);
+ }
+ }
+ else
+ {
+ variableOut->type = GLVariableType(type);
+ variableOut->precision = GLVariablePrecision(type);
+ }
+
+ const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
+ if (!arraySizes.empty())
+ {
+ variableOut->arraySizes.assign(arraySizes.begin(), arraySizes.end());
+
+ if (arraySizes[0] == 0)
+ {
+ // Tessellation Control & Evaluation shader inputs:
+ // Declaring an array size is optional. If no size is specified, it will be taken from
+ // the implementation-dependent maximum patch size (gl_MaxPatchVertices).
+ if (type.getQualifier() == EvqTessControlIn ||
+ type.getQualifier() == EvqTessEvaluationIn)
+ {
+ variableOut->arraySizes[0] = mResources.MaxPatchVertices;
+ }
+
+ // Tessellation Control shader outputs:
+ // Declaring an array size is optional. If no size is specified, it will be taken from
+ // output patch size declared in the shader.
+ if (type.getQualifier() == EvqTessControlOut)
+ {
+ ASSERT(mTessControlShaderOutputVertices > 0);
+ variableOut->arraySizes[0] = mTessControlShaderOutputVertices;
+ }
+ }
+ }
+}
+
+void CollectVariablesTraverser::setFieldProperties(const TType &type,
+ const ImmutableString &name,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ SymbolType symbolType,
+ ShaderVariable *variableOut) const
+{
+ ASSERT(variableOut);
+ setFieldOrVariableProperties(type, staticUse, isShaderIOBlock, isPatch, variableOut);
+ variableOut->name.assign(name.data(), name.length());
+ variableOut->mappedName = (symbolType == SymbolType::BuiltIn)
+ ? name.data()
+ : HashName(name, mHashFunction, nullptr).data();
+}
+
+void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
+ const TVariable &variable,
+ ShaderVariable *variableOut) const
+{
+ ASSERT(variableOut);
+ ASSERT(type.getInterfaceBlock() == nullptr || IsShaderIoBlock(type.getQualifier()) ||
+ type.getQualifier() == EvqPatchIn || type.getQualifier() == EvqPatchOut);
+
+ const bool staticUse = mSymbolTable->isStaticallyUsed(variable);
+ const bool isShaderIOBlock = type.getInterfaceBlock() != nullptr;
+ const bool isPatch = type.getQualifier() == EvqPatchIn || type.getQualifier() == EvqPatchOut;
+
+ setFieldOrVariableProperties(type, staticUse, isShaderIOBlock, isPatch, variableOut);
+
+ const bool isNamed = variable.symbolType() != SymbolType::Empty;
+
+ ASSERT(isNamed || isShaderIOBlock);
+ if (isNamed)
+ {
+ variableOut->name.assign(variable.name().data(), variable.name().length());
+ variableOut->mappedName = getMappedName(&variable);
+ }
+
+ // For I/O blocks, additionally store the name of the block as blockName. If the variable is
+ // unnamed, this name will be used instead for the purpose of interface matching.
+ if (isShaderIOBlock)
+ {
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ ASSERT(interfaceBlock);
+
+ variableOut->structOrBlockName.assign(interfaceBlock->name().data(),
+ interfaceBlock->name().length());
+ variableOut->mappedStructOrBlockName =
+ HashName(interfaceBlock->name(), mHashFunction, nullptr).data();
+ variableOut->isShaderIOBlock = true;
+ }
+}
+
+ShaderVariable CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
+{
+ const TType &type = variable.getType();
+ ASSERT(!type.getStruct());
+
+ ShaderVariable attribute;
+ setCommonVariableProperties(type, variable.variable(), &attribute);
+
+ attribute.location = type.getLayoutQualifier().location;
+ return attribute;
+}
+
+ShaderVariable CollectVariablesTraverser::recordOutputVariable(const TIntermSymbol &variable) const
+{
+ const TType &type = variable.getType();
+ ASSERT(!type.getStruct());
+
+ ShaderVariable outputVariable;
+ setCommonVariableProperties(type, variable.variable(), &outputVariable);
+
+ outputVariable.location = type.getLayoutQualifier().location;
+ outputVariable.index = type.getLayoutQualifier().index;
+ outputVariable.yuv = type.getLayoutQualifier().yuv;
+ return outputVariable;
+}
+
+ShaderVariable CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable) const
+{
+ const TType &type = variable.getType();
+
+ ShaderVariable varying;
+ setCommonVariableProperties(type, variable.variable(), &varying);
+ varying.location = type.getLayoutQualifier().location;
+
+ switch (type.getQualifier())
+ {
+ case EvqVaryingIn:
+ case EvqVaryingOut:
+ case EvqVertexOut:
+ case EvqSmoothOut:
+ case EvqFlatOut:
+ case EvqNoPerspectiveOut:
+ case EvqCentroidOut:
+ case EvqGeometryOut:
+ case EvqSampleOut:
+ if (mSymbolTable->isVaryingInvariant(variable.variable()) || type.isInvariant())
+ {
+ varying.isInvariant = true;
+ }
+ break;
+ case EvqPatchIn:
+ case EvqPatchOut:
+ varying.isPatch = true;
+ break;
+ default:
+ break;
+ }
+
+ varying.interpolation = GetInterpolationType(type.getQualifier());
+
+ // Shader I/O block properties
+ if (type.getBasicType() == EbtInterfaceBlock)
+ {
+ bool isBlockImplicitLocation = false;
+ int location = type.getLayoutQualifier().location;
+
+ // when a interface has not location in layout, assign to the zero.
+ if (location < 0)
+ {
+ location = 0;
+ isBlockImplicitLocation = true;
+ }
+
+ const TInterfaceBlock *blockType = type.getInterfaceBlock();
+ ASSERT(blockType->fields().size() == varying.fields.size());
+
+ for (size_t fieldIndex = 0; fieldIndex < varying.fields.size(); ++fieldIndex)
+ {
+ const TField *blockField = blockType->fields()[fieldIndex];
+ ShaderVariable &fieldVariable = varying.fields[fieldIndex];
+ const TType &fieldType = *blockField->type();
+
+ fieldVariable.hasImplicitLocation = isBlockImplicitLocation;
+ fieldVariable.isPatch = varying.isPatch;
+
+ int fieldLocation = fieldType.getLayoutQualifier().location;
+ if (fieldLocation >= 0)
+ {
+ fieldVariable.hasImplicitLocation = false;
+ fieldVariable.location = fieldLocation;
+ location = fieldLocation;
+ }
+ else
+ {
+ fieldVariable.location = location;
+ location += fieldType.getLocationCount();
+ }
+
+ if (fieldType.getQualifier() != EvqGlobal)
+ {
+ fieldVariable.interpolation = GetFieldInterpolationType(fieldType.getQualifier());
+ }
+ }
+ }
+
+ return varying;
+}
+
+void CollectVariablesTraverser::recordInterfaceBlock(const char *instanceName,
+ const TType &interfaceBlockType,
+ InterfaceBlock *interfaceBlock) const
+{
+ ASSERT(interfaceBlockType.getBasicType() == EbtInterfaceBlock);
+ ASSERT(interfaceBlock);
+
+ const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock();
+ ASSERT(blockType);
+
+ interfaceBlock->name = blockType->name().data();
+ interfaceBlock->mappedName = getMappedName(blockType);
+
+ const bool isGLInBuiltin = (instanceName != nullptr) && strncmp(instanceName, "gl_in", 5u) == 0;
+ if (instanceName != nullptr)
+ {
+ interfaceBlock->instanceName = instanceName;
+ const TSymbol *blockSymbol = nullptr;
+ if (isGLInBuiltin)
+ {
+ blockSymbol = mSymbolTable->getGlInVariableWithArraySize();
+ }
+ else
+ {
+ blockSymbol = mSymbolTable->findGlobal(ImmutableString(instanceName));
+ }
+ ASSERT(blockSymbol && blockSymbol->isVariable());
+ interfaceBlock->staticUse =
+ mSymbolTable->isStaticallyUsed(*static_cast<const TVariable *>(blockSymbol));
+ }
+
+ ASSERT(!interfaceBlockType.isArrayOfArrays()); // Disallowed by GLSL ES 3.10 section 4.3.9
+ interfaceBlock->arraySize =
+ interfaceBlockType.isArray() ? interfaceBlockType.getOutermostArraySize() : 0;
+
+ interfaceBlock->blockType = GetBlockType(interfaceBlockType.getQualifier());
+ if (interfaceBlock->blockType == BlockType::BLOCK_UNIFORM ||
+ interfaceBlock->blockType == BlockType::BLOCK_BUFFER)
+ {
+ // TODO(oetuaho): Remove setting isRowMajorLayout.
+ interfaceBlock->isRowMajorLayout = false;
+ interfaceBlock->binding = blockType->blockBinding();
+ interfaceBlock->layout = GetBlockLayoutType(blockType->blockStorage());
+ }
+
+ // Gather field information
+ bool anyFieldStaticallyUsed = false;
+
+ for (const TField *field : blockType->fields())
+ {
+ const TType &fieldType = *field->type();
+
+ bool staticUse = false;
+ if (instanceName == nullptr)
+ {
+ // Static use of individual fields has been recorded, since they are present in the
+ // symbol table as variables.
+ const TSymbol *fieldSymbol = mSymbolTable->findGlobal(field->name());
+ ASSERT(fieldSymbol && fieldSymbol->isVariable());
+ staticUse =
+ mSymbolTable->isStaticallyUsed(*static_cast<const TVariable *>(fieldSymbol));
+ if (staticUse)
+ {
+ anyFieldStaticallyUsed = true;
+ }
+ }
+
+ ShaderVariable fieldVariable;
+ setFieldProperties(fieldType, field->name(), staticUse, false, false, field->symbolType(),
+ &fieldVariable);
+ fieldVariable.isRowMajorLayout =
+ (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
+ interfaceBlock->fields.push_back(fieldVariable);
+ }
+ if (anyFieldStaticallyUsed)
+ {
+ interfaceBlock->staticUse = true;
+ }
+}
+
+ShaderVariable CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const
+{
+ ShaderVariable uniform;
+ setCommonVariableProperties(variable.getType(), variable.variable(), &uniform);
+ uniform.binding = variable.getType().getLayoutQualifier().binding;
+ uniform.imageUnitFormat =
+ GetImageInternalFormatType(variable.getType().getLayoutQualifier().imageInternalFormat);
+ uniform.location = variable.getType().getLayoutQualifier().location;
+ uniform.offset = variable.getType().getLayoutQualifier().offset;
+ uniform.rasterOrdered = variable.getType().getLayoutQualifier().rasterOrdered;
+ uniform.readonly = variable.getType().getMemoryQualifier().readonly;
+ uniform.writeonly = variable.getType().getMemoryQualifier().writeonly;
+ return uniform;
+}
+
+bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+ ASSERT(!sequence.empty());
+
+ const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
+ TQualifier qualifier = typedNode.getQualifier();
+
+ bool isShaderVariable = qualifier == EvqAttribute || qualifier == EvqVertexIn ||
+ qualifier == EvqFragmentOut || qualifier == EvqFragmentInOut ||
+ qualifier == EvqUniform || IsVarying(qualifier);
+
+ if (typedNode.getBasicType() != EbtInterfaceBlock && !isShaderVariable)
+ {
+ return true;
+ }
+
+ for (TIntermNode *variableNode : sequence)
+ {
+ // The only case in which the sequence will not contain a TIntermSymbol node is
+ // initialization. It will contain a TInterBinary node in that case. Since attributes,
+ // uniforms, varyings, outputs and interface blocks cannot be initialized in a shader, we
+ // must have only TIntermSymbol nodes in the sequence in the cases we are interested in.
+ const TIntermSymbol &variable = *variableNode->getAsSymbolNode();
+ if (variable.variable().symbolType() == SymbolType::AngleInternal)
+ {
+ // Internal variables are not collected.
+ continue;
+ }
+
+ // SpirvTransformer::transform uses a map of ShaderVariables, it needs member variables and
+ // (named or unnamed) structure as ShaderVariable. at link between two shaders, validation
+ // between of named and unnamed, needs the same structure, its members, and members order
+ // except instance name.
+ if (typedNode.getBasicType() == EbtInterfaceBlock && !IsShaderIoBlock(qualifier) &&
+ qualifier != EvqPatchIn && qualifier != EvqPatchOut)
+ {
+ InterfaceBlock interfaceBlock;
+ bool isUnnamed = variable.variable().symbolType() == SymbolType::Empty;
+ const TType &type = variable.getType();
+ recordInterfaceBlock(isUnnamed ? nullptr : variable.getName().data(), type,
+ &interfaceBlock);
+
+ // all fields in interface block will be added for updating interface variables because
+ // the temporal structure variable will be ignored.
+ switch (qualifier)
+ {
+ case EvqUniform:
+ mUniformBlocks->push_back(interfaceBlock);
+ break;
+ case EvqBuffer:
+ mShaderStorageBlocks->push_back(interfaceBlock);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ ASSERT(variable.variable().symbolType() != SymbolType::Empty ||
+ IsShaderIoBlock(qualifier) || qualifier == EvqPatchIn ||
+ qualifier == EvqPatchOut);
+ switch (qualifier)
+ {
+ case EvqAttribute:
+ case EvqVertexIn:
+ mAttribs->push_back(recordAttribute(variable));
+ break;
+ case EvqFragmentOut:
+ case EvqFragmentInOut:
+ mOutputVariables->push_back(recordOutputVariable(variable));
+ break;
+ case EvqUniform:
+ mUniforms->push_back(recordUniform(variable));
+ break;
+ default:
+ if (IsVaryingIn(qualifier))
+ {
+ mInputVaryings->push_back(recordVarying(variable));
+ }
+ else
+ {
+ ASSERT(IsVaryingOut(qualifier));
+ mOutputVaryings->push_back(recordVarying(variable));
+ }
+ break;
+ }
+ }
+ }
+
+ // None of the recorded variables can have initializers, so we don't need to traverse the
+ // declarators.
+ return false;
+}
+
+InterfaceBlock *CollectVariablesTraverser::findNamedInterfaceBlock(
+ const ImmutableString &blockName) const
+{
+ InterfaceBlock *namedBlock = FindVariable(blockName, mUniformBlocks);
+ if (!namedBlock)
+ {
+ namedBlock = FindVariable(blockName, mShaderStorageBlocks);
+ }
+ return namedBlock;
+}
+
+bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
+{
+ if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
+ {
+ // NOTE: we do not determine static use / activeness for individual blocks of an array.
+ TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped();
+ ASSERT(blockNode);
+
+ TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
+ ASSERT(constantUnion);
+
+ InterfaceBlock *namedBlock = nullptr;
+
+ bool traverseIndexExpression = false;
+ TIntermBinary *interfaceIndexingNode = blockNode->getAsBinaryNode();
+ if (interfaceIndexingNode)
+ {
+ ASSERT(interfaceIndexingNode->getOp() == EOpIndexDirect ||
+ interfaceIndexingNode->getOp() == EOpIndexIndirect);
+ traverseIndexExpression = true;
+ blockNode = interfaceIndexingNode->getLeft();
+ }
+
+ const TType &interfaceNodeType = blockNode->getType();
+ const TInterfaceBlock *interfaceBlock = interfaceNodeType.getInterfaceBlock();
+ const TQualifier qualifier = interfaceNodeType.getQualifier();
+
+ // If it's a shader I/O block, look in varyings
+ ShaderVariable *ioBlockVar = nullptr;
+ if (qualifier == EvqPerVertexIn)
+ {
+ TIntermSymbol *symbolNode = blockNode->getAsSymbolNode();
+ ASSERT(symbolNode);
+ recordBuiltInVaryingUsed(symbolNode->variable(), &mPerVertexInAdded, mInputVaryings);
+ ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mInputVaryings);
+ }
+ else if (IsVaryingIn(qualifier))
+ {
+ ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mInputVaryings);
+ }
+ else if (qualifier == EvqPerVertexOut)
+ {
+ TIntermSymbol *symbolNode = blockNode->getAsSymbolNode();
+ ASSERT(symbolNode);
+ recordBuiltInVaryingUsed(symbolNode->variable(), &mPerVertexOutAdded, mOutputVaryings);
+ ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mOutputVaryings);
+ }
+ else if (IsVaryingOut(qualifier))
+ {
+ ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mOutputVaryings);
+ }
+
+ if (ioBlockVar)
+ {
+ MarkActive(ioBlockVar);
+ }
+ else
+ {
+ if (!namedBlock)
+ {
+ namedBlock = findNamedInterfaceBlock(interfaceBlock->name());
+ }
+ ASSERT(namedBlock);
+ ASSERT(namedBlock->staticUse);
+ namedBlock->active = true;
+ unsigned int fieldIndex = static_cast<unsigned int>(constantUnion->getIConst(0));
+ ASSERT(fieldIndex < namedBlock->fields.size());
+ // TODO(oetuaho): Would be nicer to record static use of fields of named interface
+ // blocks more accurately at parse time - now we only mark the fields statically used if
+ // they are active. http://anglebug.com/2440 We need to mark this field and all of its
+ // sub-fields, as static/active
+ MarkActive(&namedBlock->fields[fieldIndex]);
+ }
+
+ if (traverseIndexExpression)
+ {
+ ASSERT(interfaceIndexingNode);
+ interfaceIndexingNode->getRight()->traverse(this);
+ }
+ return false;
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+void CollectVariables(TIntermBlock *root,
+ std::vector<ShaderVariable> *attributes,
+ std::vector<ShaderVariable> *outputVariables,
+ std::vector<ShaderVariable> *uniforms,
+ std::vector<ShaderVariable> *inputVaryings,
+ std::vector<ShaderVariable> *outputVaryings,
+ std::vector<ShaderVariable> *sharedVariables,
+ std::vector<InterfaceBlock> *uniformBlocks,
+ std::vector<InterfaceBlock> *shaderStorageBlocks,
+ ShHashFunction64 hashFunction,
+ TSymbolTable *symbolTable,
+ GLenum shaderType,
+ const TExtensionBehavior &extensionBehavior,
+ const ShBuiltInResources &resources,
+ int tessControlShaderOutputVertices)
+{
+ CollectVariablesTraverser collect(
+ attributes, outputVariables, uniforms, inputVaryings, outputVaryings, sharedVariables,
+ uniformBlocks, shaderStorageBlocks, hashFunction, symbolTable, shaderType,
+ extensionBehavior, resources, tessControlShaderOutputVertices);
+ root->traverse(&collect);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/CollectVariables.h b/gfx/angle/checkout/src/compiler/translator/CollectVariables.h
new file mode 100644
index 0000000000..6ea4b172a0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/CollectVariables.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// CollectVariables.h: Collect lists of shader interface variables based on the AST.
+
+#ifndef COMPILER_TRANSLATOR_COLLECTVARIABLES_H_
+#define COMPILER_TRANSLATOR_COLLECTVARIABLES_H_
+
+#include <GLSLANG/ShaderLang.h>
+
+#include "compiler/translator/ExtensionBehavior.h"
+
+namespace sh
+{
+
+class TIntermBlock;
+class TSymbolTable;
+
+void CollectVariables(TIntermBlock *root,
+ std::vector<ShaderVariable> *attributes,
+ std::vector<ShaderVariable> *outputVariables,
+ std::vector<ShaderVariable> *uniforms,
+ std::vector<ShaderVariable> *inputVaryings,
+ std::vector<ShaderVariable> *outputVaryings,
+ std::vector<ShaderVariable> *sharedVariables,
+ std::vector<InterfaceBlock> *uniformBlocks,
+ std::vector<InterfaceBlock> *shaderStorageBlocks,
+ ShHashFunction64 hashFunction,
+ TSymbolTable *symbolTable,
+ GLenum shaderType,
+ const TExtensionBehavior &extensionBehavior,
+ const ShBuiltInResources &resources,
+ int tessControlShaderOutputVertices);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_COLLECTVARIABLES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Common.h b/gfx/angle/checkout/src/compiler/translator/Common.h
new file mode 100644
index 0000000000..77907fc3a4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Common.h
@@ -0,0 +1,256 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_COMMON_H_
+#define COMPILER_TRANSLATOR_COMMON_H_
+
+#include <stdio.h>
+#include <limits>
+#include <map>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+#include "common/third_party/smhasher/src/PMurHash.h"
+#include "compiler/translator/PoolAlloc.h"
+
+namespace sh
+{
+
+struct TSourceLoc
+{
+ int first_file;
+ int first_line;
+ int last_file;
+ int last_line;
+};
+
+constexpr TSourceLoc kNoSourceLoc{-1, -1, -1, -1};
+
+//
+// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
+//
+#define POOL_ALLOCATOR_NEW_DELETE \
+ void *operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
+ void *operator new(size_t, void *_Where) { return (_Where); } \
+ void operator delete(void *) {} \
+ void operator delete(void *, void *) {} \
+ void *operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
+ void *operator new[](size_t, void *_Where) { return (_Where); } \
+ void operator delete[](void *) {} \
+ void operator delete[](void *, void *) {}
+
+//
+// Pool version of string.
+//
+typedef pool_allocator<char> TStringAllocator;
+typedef std::basic_string<char, std::char_traits<char>, TStringAllocator> TString;
+typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;
+
+//
+// Persistent memory. Should only be used for strings that survive across compiles.
+//
+using TPersistString = std::string;
+using TPersistStringStream = std::ostringstream;
+
+//
+// Pool allocator versions of vectors, lists, and maps
+//
+template <class T>
+class TVector : public std::vector<T, pool_allocator<T>>
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+
+ typedef typename std::vector<T, pool_allocator<T>>::size_type size_type;
+ TVector() : std::vector<T, pool_allocator<T>>() {}
+ TVector(const pool_allocator<T> &a) : std::vector<T, pool_allocator<T>>(a) {}
+ TVector(size_type i) : std::vector<T, pool_allocator<T>>(i) {}
+ TVector(size_type i, const T &value) : std::vector<T, pool_allocator<T>>(i, value) {}
+ template <typename InputIt>
+ TVector(InputIt first, InputIt last) : std::vector<T, pool_allocator<T>>(first, last)
+ {}
+ TVector(std::initializer_list<T> init) : std::vector<T, pool_allocator<T>>(init) {}
+};
+
+template <class K, class D, class H = std::hash<K>, class CMP = std::equal_to<K>>
+class TUnorderedMap : public std::unordered_map<K, D, H, CMP, pool_allocator<std::pair<const K, D>>>
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ typedef pool_allocator<std::pair<const K, D>> tAllocator;
+
+ TUnorderedMap() : std::unordered_map<K, D, H, CMP, tAllocator>() {}
+ // use correct two-stage name lookup supported in gcc 3.4 and above
+ TUnorderedMap(const tAllocator &a)
+ : std::unordered_map<K, D, H, CMP, tAllocator>(
+ std::unordered_map<K, D, H, CMP, tAllocator>::key_compare(),
+ a)
+ {}
+};
+
+template <class K, class D, class CMP = std::less<K>>
+class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<const K, D>>>
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ typedef pool_allocator<std::pair<const K, D>> tAllocator;
+
+ TMap() : std::map<K, D, CMP, tAllocator>() {}
+ // use correct two-stage name lookup supported in gcc 3.4 and above
+ TMap(const tAllocator &a)
+ : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a)
+ {}
+};
+
+// Basic implementation of C++20's span for use with pool-allocated containers (TVector) or static
+// arrays. This is used by the array sizes member of TType to allow arrayed types to be
+// constexpr-constructed.
+// See the reference for std::span here: https://en.cppreference.com/w/cpp/container/span
+template <typename T>
+class TSpan
+{
+ public:
+ typedef size_t size_type;
+
+ constexpr TSpan() {}
+ constexpr TSpan(T *ptr, size_type size) : mData(ptr), mSize(size) {}
+
+ constexpr TSpan(const TSpan &that) : mData(that.mData), mSize(that.mSize) {}
+ constexpr TSpan &operator=(const TSpan &that)
+ {
+ mData = that.mData;
+ mSize = that.mSize;
+ return *this;
+ }
+
+ // Note: the pointer is taken out of the TVector because TVector's memory is pool allocated,
+ // so the memory will live on even if the TVector is destroyed.
+ template <typename S>
+ TSpan(const TVector<S> &vec) : mData(vec.data()), mSize(vec.size())
+ {}
+ template <typename S>
+ TSpan &operator=(const TVector<S> &vec)
+ {
+ mData = vec.data();
+ mSize = vec.size();
+ return *this;
+ }
+
+ constexpr bool operator==(const TSpan &that) const
+ {
+ if (mSize != that.mSize)
+ {
+ return false;
+ }
+
+ if (mData == that.mData)
+ {
+ return true;
+ }
+
+ for (size_type index = 0; index < mSize; ++index)
+ {
+ if (mData[index] != that.mData[index])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ constexpr bool operator!=(const TSpan &that) const { return !(*this == that); }
+
+ constexpr T *data() const { return mData; }
+ constexpr size_type size() const { return mSize; }
+ constexpr bool empty() const { return mSize == 0; }
+
+ constexpr T &operator[](size_type index) const { return mData[index]; }
+ constexpr T &front() const { return mData[0]; }
+ constexpr T &back() const { return mData[mSize - 1]; }
+
+ constexpr T *begin() const { return mData; }
+ constexpr T *end() const { return mData + mSize; }
+
+ constexpr std::reverse_iterator<T *> rbegin() const
+ {
+ return std::make_reverse_iterator(end());
+ }
+ constexpr std::reverse_iterator<T *> rend() const
+ {
+ return std::make_reverse_iterator(begin());
+ }
+
+ constexpr TSpan first(size_type count) const
+ {
+ ASSERT(count <= mSize);
+ return count == 0 ? TSpan() : TSpan(mData, count);
+ }
+ constexpr TSpan last(size_type count) const
+ {
+ ASSERT(count <= mSize);
+ return count == 0 ? TSpan() : TSpan(mData + mSize - count, count);
+ }
+ constexpr TSpan subspan(size_type offset, size_type count) const
+ {
+ ASSERT(offset + count <= mSize);
+ return count == 0 ? TSpan() : TSpan(mData + offset, count);
+ }
+
+ private:
+ T *mData = nullptr;
+ size_t mSize = 0;
+};
+
+// Integer to TString conversion
+template <typename T>
+inline TString str(T i)
+{
+ ASSERT(std::numeric_limits<T>::is_integer);
+ char buffer[((8 * sizeof(T)) / 3) + 3];
+ const char *formatStr = std::numeric_limits<T>::is_signed ? "%d" : "%u";
+ snprintf(buffer, sizeof(buffer), formatStr, i);
+ return buffer;
+}
+
+// Allocate a char array in the global memory pool. str must be a null terminated string. strLength
+// is the length without the null terminator.
+inline const char *AllocatePoolCharArray(const char *str, size_t strLength)
+{
+ size_t requiredSize = strLength + 1;
+ char *buffer = static_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize));
+ memcpy(buffer, str, requiredSize);
+ ASSERT(buffer[strLength] == '\0');
+ return buffer;
+}
+
+// Initialize a new stream which must be imbued with the classic locale
+template <typename T>
+T InitializeStream()
+{
+ T stream;
+ stream.imbue(std::locale::classic());
+ return stream;
+}
+
+} // namespace sh
+
+namespace std
+{
+template <>
+struct hash<sh::TString>
+{
+ size_t operator()(const sh::TString &s) const
+ {
+ return angle::PMurHash32(0, s.data(), static_cast<int>(s.length()));
+ }
+};
+} // namespace std
+
+#endif // COMPILER_TRANSLATOR_COMMON_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Compiler.cpp b/gfx/angle/checkout/src/compiler/translator/Compiler.cpp
new file mode 100644
index 0000000000..891d1ddf61
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Compiler.cpp
@@ -0,0 +1,1746 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/Compiler.h"
+
+#include <sstream>
+
+#include "angle_gl.h"
+#include "common/utilities.h"
+#include "compiler/translator/CallDAG.h"
+#include "compiler/translator/CollectVariables.h"
+#include "compiler/translator/Initialize.h"
+#include "compiler/translator/IsASTDepthBelowLimit.h"
+#include "compiler/translator/OutputTree.h"
+#include "compiler/translator/ParseContext.h"
+#include "compiler/translator/ValidateBarrierFunctionCall.h"
+#include "compiler/translator/ValidateClipCullDistance.h"
+#include "compiler/translator/ValidateLimitations.h"
+#include "compiler/translator/ValidateMaxParameters.h"
+#include "compiler/translator/ValidateOutputs.h"
+#include "compiler/translator/ValidateTypeSizeLimitations.h"
+#include "compiler/translator/ValidateVaryingLocations.h"
+#include "compiler/translator/VariablePacker.h"
+#include "compiler/translator/tree_ops/ClampIndirectIndices.h"
+#include "compiler/translator/tree_ops/ClampPointSize.h"
+#include "compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h"
+#include "compiler/translator/tree_ops/DeferGlobalInitializers.h"
+#include "compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h"
+#include "compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h"
+#include "compiler/translator/tree_ops/FoldExpressions.h"
+#include "compiler/translator/tree_ops/ForcePrecisionQualifier.h"
+#include "compiler/translator/tree_ops/InitializeVariables.h"
+#include "compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h"
+#include "compiler/translator/tree_ops/PruneEmptyCases.h"
+#include "compiler/translator/tree_ops/PruneNoOps.h"
+#include "compiler/translator/tree_ops/RemoveArrayLengthMethod.h"
+#include "compiler/translator/tree_ops/RemoveDynamicIndexing.h"
+#include "compiler/translator/tree_ops/RemoveInvariantDeclaration.h"
+#include "compiler/translator/tree_ops/RemoveUnreferencedVariables.h"
+#include "compiler/translator/tree_ops/RewritePixelLocalStorage.h"
+#include "compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h"
+#include "compiler/translator/tree_ops/SeparateDeclarations.h"
+#include "compiler/translator/tree_ops/SimplifyLoopConditions.h"
+#include "compiler/translator/tree_ops/SplitSequenceOperator.h"
+#include "compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h"
+#include "compiler/translator/tree_ops/apple/RewriteDoWhile.h"
+#include "compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h"
+#include "compiler/translator/tree_ops/gl/ClampFragDepth.h"
+#include "compiler/translator/tree_ops/gl/RegenerateStructNames.h"
+#include "compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h"
+#include "compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/ReplaceShadowingVariables.h"
+#include "compiler/translator/util.h"
+
+// #define ANGLE_FUZZER_CORPUS_OUTPUT_DIR "corpus/"
+
+#if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
+# include "common/hash_utils.h"
+# include "common/mathutil.h"
+#endif
+
+namespace sh
+{
+
+namespace
+{
+// Helper that returns if a top-level node is unused. If it's a function, the function prototype is
+// returned as well.
+bool IsTopLevelNodeUnusedFunction(const CallDAG &callDag,
+ const std::vector<TFunctionMetadata> &metadata,
+ TIntermNode *node,
+ const TFunction **functionOut)
+{
+ const TIntermFunctionPrototype *asFunctionPrototype = node->getAsFunctionPrototypeNode();
+ const TIntermFunctionDefinition *asFunctionDefinition = node->getAsFunctionDefinition();
+
+ *functionOut = nullptr;
+
+ if (asFunctionDefinition)
+ {
+ *functionOut = asFunctionDefinition->getFunction();
+ }
+ else if (asFunctionPrototype)
+ {
+ *functionOut = asFunctionPrototype->getFunction();
+ }
+ if (*functionOut == nullptr)
+ {
+ return false;
+ }
+
+ size_t callDagIndex = callDag.findIndex((*functionOut)->uniqueId());
+ if (callDagIndex == CallDAG::InvalidIndex)
+ {
+ // This happens only for unimplemented prototypes which are thus unused
+ ASSERT(asFunctionPrototype);
+ return true;
+ }
+
+ ASSERT(callDagIndex < metadata.size());
+ return !metadata[callDagIndex].used;
+}
+
+#if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
+void DumpFuzzerCase(char const *const *shaderStrings,
+ size_t numStrings,
+ uint32_t type,
+ uint32_t spec,
+ uint32_t output,
+ const ShCompileOptions &options)
+{
+ ShaderDumpHeader header{};
+ header.type = type;
+ header.spec = spec;
+ header.output = output;
+ memcpy(&header.basicCompileOptions, &options, offsetof(ShCompileOptions, metal));
+ static_assert(offsetof(ShCompileOptions, metal) <= sizeof(header.basicCompileOptions));
+ memcpy(&header.metalCompileOptions, &options.metal, sizeof(options.metal));
+ static_assert(sizeof(options.metal) <= sizeof(header.metalCompileOptions));
+ memcpy(&header.plsCompileOptions, &options.pls, sizeof(options.pls));
+ static_assert(sizeof(options.pls) <= sizeof(header.plsCompileOptions));
+ size_t contentsLength = sizeof(header) + 1; // Extra: header + nul terminator.
+ for (size_t i = 0; i < numStrings; i++)
+ {
+ contentsLength += strlen(shaderStrings[i]);
+ }
+ std::vector<uint8_t> contents(rx::roundUp<size_t>(contentsLength, 4), 0);
+ memcpy(&contents[0], &header, sizeof(header));
+ uint8_t *data = &contents[sizeof(header)];
+ for (size_t i = 0; i < numStrings; i++)
+ {
+ auto length = strlen(shaderStrings[i]);
+ memcpy(data, shaderStrings[i], length);
+ data += length;
+ }
+ auto hash = angle::ComputeGenericHash(contents.data(), contents.size());
+
+ std::ostringstream o = sh::InitializeStream<std::ostringstream>();
+ o << ANGLE_FUZZER_CORPUS_OUTPUT_DIR << std::hex << std::setw(16) << std::setfill('0') << hash
+ << ".sample";
+ std::string s = o.str();
+
+ // Must match the input format of the fuzzer
+ FILE *f = fopen(s.c_str(), "w");
+ fwrite(contents.data(), sizeof(char), contentsLength, f);
+ fclose(f);
+}
+#endif // defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
+} // anonymous namespace
+
+bool IsGLSL130OrNewer(ShShaderOutput output)
+{
+ return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
+ output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
+ output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT ||
+ output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
+ output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
+}
+
+bool IsGLSL420OrNewer(ShShaderOutput output)
+{
+ return (output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
+ output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
+}
+
+bool IsGLSL410OrOlder(ShShaderOutput output)
+{
+ return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
+ output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
+ output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT);
+}
+
+bool RemoveInvariant(sh::GLenum shaderType,
+ int shaderVersion,
+ ShShaderOutput outputType,
+ const ShCompileOptions &compileOptions)
+{
+ if (shaderType == GL_FRAGMENT_SHADER && IsGLSL420OrNewer(outputType))
+ return true;
+
+ if (compileOptions.removeInvariantAndCentroidForESSL3 && shaderVersion >= 300 &&
+ shaderType == GL_VERTEX_SHADER)
+ return true;
+
+ return false;
+}
+
+size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
+{
+ // WebGL defines a max token length of 256, while ES2 leaves max token
+ // size undefined. ES3 defines a max size of 1024 characters.
+ switch (spec)
+ {
+ case SH_WEBGL_SPEC:
+ return 256;
+ default:
+ return 1024;
+ }
+}
+
+int GetMaxUniformVectorsForShaderType(GLenum shaderType, const ShBuiltInResources &resources)
+{
+ switch (shaderType)
+ {
+ case GL_VERTEX_SHADER:
+ return resources.MaxVertexUniformVectors;
+ case GL_FRAGMENT_SHADER:
+ return resources.MaxFragmentUniformVectors;
+
+ // TODO (jiawei.shao@intel.com): check if we need finer-grained component counting
+ case GL_COMPUTE_SHADER:
+ return resources.MaxComputeUniformComponents / 4;
+ case GL_GEOMETRY_SHADER_EXT:
+ return resources.MaxGeometryUniformComponents / 4;
+ default:
+ UNREACHABLE();
+ return -1;
+ }
+}
+
+namespace
+{
+
+class [[nodiscard]] TScopedPoolAllocator
+{
+ public:
+ TScopedPoolAllocator(angle::PoolAllocator *allocator) : mAllocator(allocator)
+ {
+ mAllocator->push();
+ SetGlobalPoolAllocator(mAllocator);
+ }
+ ~TScopedPoolAllocator()
+ {
+ SetGlobalPoolAllocator(nullptr);
+ mAllocator->pop();
+ }
+
+ private:
+ angle::PoolAllocator *mAllocator;
+};
+
+class [[nodiscard]] TScopedSymbolTableLevel
+{
+ public:
+ TScopedSymbolTableLevel(TSymbolTable *table) : mTable(table)
+ {
+ ASSERT(mTable->isEmpty());
+ mTable->push();
+ }
+ ~TScopedSymbolTableLevel()
+ {
+ while (!mTable->isEmpty())
+ mTable->pop();
+ }
+
+ private:
+ TSymbolTable *mTable;
+};
+
+int GetMaxShaderVersionForSpec(ShShaderSpec spec)
+{
+ switch (spec)
+ {
+ case SH_GLES2_SPEC:
+ case SH_WEBGL_SPEC:
+ return 100;
+ case SH_GLES3_SPEC:
+ case SH_WEBGL2_SPEC:
+ return 300;
+ case SH_GLES3_1_SPEC:
+ case SH_WEBGL3_SPEC:
+ return 310;
+ case SH_GLES3_2_SPEC:
+ return 320;
+ case SH_GL_CORE_SPEC:
+ case SH_GL_COMPATIBILITY_SPEC:
+ return 460;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+bool ValidateFragColorAndFragData(GLenum shaderType,
+ int shaderVersion,
+ const TSymbolTable &symbolTable,
+ TDiagnostics *diagnostics)
+{
+ if (shaderVersion > 100 || shaderType != GL_FRAGMENT_SHADER)
+ {
+ return true;
+ }
+
+ bool usesFragColor = false;
+ bool usesFragData = false;
+ // This validation is a bit stricter than the spec - it's only an error to write to
+ // both FragData and FragColor. But because it's better not to have reads from undefined
+ // variables, we always return an error if they are both referenced, rather than only if they
+ // are written.
+ if (symbolTable.isStaticallyUsed(*BuiltInVariable::gl_FragColor()) ||
+ symbolTable.isStaticallyUsed(*BuiltInVariable::gl_SecondaryFragColorEXT()))
+ {
+ usesFragColor = true;
+ }
+ // Extension variables may not always be initialized (saves some time at symbol table init).
+ bool secondaryFragDataUsed =
+ symbolTable.gl_SecondaryFragDataEXT() != nullptr &&
+ symbolTable.isStaticallyUsed(*symbolTable.gl_SecondaryFragDataEXT());
+ if (symbolTable.isStaticallyUsed(*symbolTable.gl_FragData()) || secondaryFragDataUsed)
+ {
+ usesFragData = true;
+ }
+ if (usesFragColor && usesFragData)
+ {
+ const char *errorMessage = "cannot use both gl_FragData and gl_FragColor";
+ if (symbolTable.isStaticallyUsed(*BuiltInVariable::gl_SecondaryFragColorEXT()) ||
+ secondaryFragDataUsed)
+ {
+ errorMessage =
+ "cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)"
+ " and (gl_FragColor, gl_SecondaryFragColorEXT)";
+ }
+ diagnostics->globalError(errorMessage);
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+TShHandleBase::TShHandleBase()
+{
+ allocator.push();
+ SetGlobalPoolAllocator(&allocator);
+}
+
+TShHandleBase::~TShHandleBase()
+{
+ SetGlobalPoolAllocator(nullptr);
+ allocator.popAll();
+}
+
+TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
+ : mVariablesCollected(false),
+ mGLPositionInitialized(false),
+ mShaderType(type),
+ mShaderSpec(spec),
+ mOutputType(output),
+ mBuiltInFunctionEmulator(),
+ mDiagnostics(mInfoSink.info),
+ mSourcePath(nullptr),
+ mComputeShaderLocalSizeDeclared(false),
+ mComputeShaderLocalSize(1),
+ mGeometryShaderMaxVertices(-1),
+ mGeometryShaderInvocations(0),
+ mGeometryShaderInputPrimitiveType(EptUndefined),
+ mGeometryShaderOutputPrimitiveType(EptUndefined),
+ mTessControlShaderOutputVertices(0),
+ mTessEvaluationShaderInputPrimitiveType(EtetUndefined),
+ mTessEvaluationShaderInputVertexSpacingType(EtetUndefined),
+ mTessEvaluationShaderInputOrderingType(EtetUndefined),
+ mTessEvaluationShaderInputPointType(EtetUndefined),
+ mHasAnyPreciseType(false),
+ mAdvancedBlendEquations(0),
+ mHasPixelLocalStorageUniforms(false),
+ mCompileOptions{}
+{}
+
+TCompiler::~TCompiler() {}
+
+bool TCompiler::isHighPrecisionSupported() const
+{
+ return mShaderVersion > 100 || mShaderType != GL_FRAGMENT_SHADER ||
+ mResources.FragmentPrecisionHigh == 1;
+}
+
+bool TCompiler::shouldRunLoopAndIndexingValidation(const ShCompileOptions &compileOptions) const
+{
+ // If compiling an ESSL 1.00 shader for WebGL, or if its been requested through the API,
+ // validate loop and indexing as well (to verify that the shader only uses minimal functionality
+ // of ESSL 1.00 as in Appendix A of the spec).
+ return (IsWebGLBasedSpec(mShaderSpec) && mShaderVersion == 100) ||
+ compileOptions.validateLoopIndexing;
+}
+
+bool TCompiler::shouldLimitTypeSizes() const
+{
+ // WebGL shaders limit the size of variables' types in shaders,
+ // including arrays, structs and interface blocks.
+ return IsWebGLBasedSpec(mShaderSpec);
+}
+
+bool TCompiler::Init(const ShBuiltInResources &resources)
+{
+ SetGlobalPoolAllocator(&allocator);
+
+ // Generate built-in symbol table.
+ if (!initBuiltInSymbolTable(resources))
+ return false;
+
+ mResources = resources;
+ setResourceString();
+
+ InitExtensionBehavior(resources, mExtensionBehavior);
+ return true;
+}
+
+TIntermBlock *TCompiler::compileTreeForTesting(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions)
+{
+ return compileTreeImpl(shaderStrings, numStrings, compileOptions);
+}
+
+TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions)
+{
+ // Remember the compile options for helper functions such as validateAST.
+ mCompileOptions = compileOptions;
+
+ clearResults();
+
+ ASSERT(numStrings > 0);
+ ASSERT(GetGlobalPoolAllocator());
+
+ // Reset the extension behavior for each compilation unit.
+ ResetExtensionBehavior(mResources, mExtensionBehavior, compileOptions);
+
+ // If gl_DrawID is not supported, remove it from the available extensions
+ // Currently we only allow emulation of gl_DrawID
+ const bool glDrawIDSupported = compileOptions.emulateGLDrawID;
+ if (!glDrawIDSupported)
+ {
+ auto it = mExtensionBehavior.find(TExtension::ANGLE_multi_draw);
+ if (it != mExtensionBehavior.end())
+ {
+ mExtensionBehavior.erase(it);
+ }
+ }
+
+ const bool glBaseVertexBaseInstanceSupported = compileOptions.emulateGLBaseVertexBaseInstance;
+ if (!glBaseVertexBaseInstanceSupported)
+ {
+ auto it =
+ mExtensionBehavior.find(TExtension::ANGLE_base_vertex_base_instance_shader_builtin);
+ if (it != mExtensionBehavior.end())
+ {
+ mExtensionBehavior.erase(it);
+ }
+ }
+
+ // First string is path of source file if flag is set. The actual source follows.
+ size_t firstSource = 0;
+ if (compileOptions.sourcePath)
+ {
+ mSourcePath = shaderStrings[0];
+ ++firstSource;
+ }
+
+ TParseContext parseContext(mSymbolTable, mExtensionBehavior, mShaderType, mShaderSpec,
+ compileOptions, !IsDesktopGLSpec(mShaderSpec), &mDiagnostics,
+ getResources(), getOutputType());
+
+ parseContext.setFragmentPrecisionHighOnESSL1(mResources.FragmentPrecisionHigh == 1);
+
+ // We preserve symbols at the built-in level from compile-to-compile.
+ // Start pushing the user-defined symbols at global level.
+ TScopedSymbolTableLevel globalLevel(&mSymbolTable);
+ ASSERT(mSymbolTable.atGlobalLevel());
+
+ // Parse shader.
+ if (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr,
+ &parseContext) != 0)
+ {
+ return nullptr;
+ }
+
+ if (!postParseChecks(parseContext))
+ {
+ return nullptr;
+ }
+
+ setASTMetadata(parseContext);
+
+ if (!checkShaderVersion(&parseContext))
+ {
+ return nullptr;
+ }
+
+ TIntermBlock *root = parseContext.getTreeRoot();
+ if (!checkAndSimplifyAST(root, parseContext, compileOptions))
+ {
+ return nullptr;
+ }
+
+ return root;
+}
+
+bool TCompiler::checkShaderVersion(TParseContext *parseContext)
+{
+ if (GetMaxShaderVersionForSpec(mShaderSpec) < mShaderVersion)
+ {
+ mDiagnostics.globalError("unsupported shader version");
+ return false;
+ }
+
+ ASSERT(parseContext);
+ switch (mShaderType)
+ {
+ case GL_COMPUTE_SHADER:
+ if (mShaderVersion < 310)
+ {
+ mDiagnostics.globalError("Compute shader is not supported in this shader version.");
+ return false;
+ }
+ break;
+
+ case GL_GEOMETRY_SHADER_EXT:
+ if (mShaderVersion < 310)
+ {
+ mDiagnostics.globalError(
+ "Geometry shader is not supported in this shader version.");
+ return false;
+ }
+ else if (mShaderVersion == 310)
+ {
+ if (!parseContext->checkCanUseOneOfExtensions(
+ sh::TSourceLoc(),
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}}))
+ {
+ return false;
+ }
+ }
+ break;
+
+ case GL_TESS_CONTROL_SHADER_EXT:
+ case GL_TESS_EVALUATION_SHADER_EXT:
+ if (mShaderVersion < 310)
+ {
+ mDiagnostics.globalError(
+ "Tessellation shaders are not supported in this shader version.");
+ return false;
+ }
+ else if (mShaderVersion == 310)
+ {
+ if (!parseContext->checkCanUseExtension(sh::TSourceLoc(),
+ TExtension::EXT_tessellation_shader))
+ {
+ return false;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+void TCompiler::setASTMetadata(const TParseContext &parseContext)
+{
+ mShaderVersion = parseContext.getShaderVersion();
+
+ mPragma = parseContext.pragma();
+ mSymbolTable.setGlobalInvariant(mPragma.stdgl.invariantAll);
+
+ mEarlyFragmentTestsSpecified = parseContext.isEarlyFragmentTestsSpecified();
+
+ mHasDiscard = parseContext.hasDiscard();
+
+ mEnablesPerSampleShading = parseContext.isSampleQualifierSpecified();
+
+ mComputeShaderLocalSizeDeclared = parseContext.isComputeShaderLocalSizeDeclared();
+ mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize();
+
+ mNumViews = parseContext.getNumViews();
+
+ mHasAnyPreciseType = parseContext.hasAnyPreciseType();
+
+ if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ mAdvancedBlendEquations = parseContext.getAdvancedBlendEquations();
+ mHasPixelLocalStorageUniforms = !parseContext.pixelLocalStorageBindings().empty();
+ }
+ if (mShaderType == GL_GEOMETRY_SHADER_EXT)
+ {
+ mGeometryShaderInputPrimitiveType = parseContext.getGeometryShaderInputPrimitiveType();
+ mGeometryShaderOutputPrimitiveType = parseContext.getGeometryShaderOutputPrimitiveType();
+ mGeometryShaderMaxVertices = parseContext.getGeometryShaderMaxVertices();
+ mGeometryShaderInvocations = parseContext.getGeometryShaderInvocations();
+ }
+ if (mShaderType == GL_TESS_CONTROL_SHADER_EXT)
+ {
+ mTessControlShaderOutputVertices = parseContext.getTessControlShaderOutputVertices();
+ }
+ if (mShaderType == GL_TESS_EVALUATION_SHADER_EXT)
+ {
+ mTessEvaluationShaderInputPrimitiveType =
+ parseContext.getTessEvaluationShaderInputPrimitiveType();
+ mTessEvaluationShaderInputVertexSpacingType =
+ parseContext.getTessEvaluationShaderInputVertexSpacingType();
+ mTessEvaluationShaderInputOrderingType =
+ parseContext.getTessEvaluationShaderInputOrderingType();
+ mTessEvaluationShaderInputPointType = parseContext.getTessEvaluationShaderInputPointType();
+ }
+}
+
+unsigned int TCompiler::getSharedMemorySize() const
+{
+ unsigned int sharedMemSize = 0;
+ for (const sh::ShaderVariable &var : mSharedVariables)
+ {
+ sharedMemSize += var.getExternalSize();
+ }
+
+ return sharedMemSize;
+}
+
+bool TCompiler::validateAST(TIntermNode *root)
+{
+ if (mCompileOptions.validateAST)
+ {
+ bool valid = ValidateAST(root, &mDiagnostics, mValidateASTOptions);
+
+#if defined(ANGLE_ENABLE_ASSERTS)
+ if (!valid)
+ {
+ OutputTree(root, mInfoSink.info);
+ fprintf(stderr, "AST validation error(s):\n%s\n", mInfoSink.info.c_str());
+ }
+#endif
+ // In debug, assert validation. In release, validation errors will be returned back to the
+ // application as internal ANGLE errors.
+ ASSERT(valid);
+
+ return valid;
+ }
+ return true;
+}
+
+bool TCompiler::disableValidateFunctionCall()
+{
+ bool wasEnabled = mValidateASTOptions.validateFunctionCall;
+ mValidateASTOptions.validateFunctionCall = false;
+ return wasEnabled;
+}
+
+void TCompiler::restoreValidateFunctionCall(bool enable)
+{
+ ASSERT(!mValidateASTOptions.validateFunctionCall);
+ mValidateASTOptions.validateFunctionCall = enable;
+}
+
+bool TCompiler::disableValidateVariableReferences()
+{
+ bool wasEnabled = mValidateASTOptions.validateVariableReferences;
+ mValidateASTOptions.validateVariableReferences = false;
+ return wasEnabled;
+}
+
+void TCompiler::restoreValidateVariableReferences(bool enable)
+{
+ ASSERT(!mValidateASTOptions.validateVariableReferences);
+ mValidateASTOptions.validateVariableReferences = enable;
+}
+
+void TCompiler::enableValidateNoMoreTransformations()
+{
+ mValidateASTOptions.validateNoMoreTransformations = true;
+}
+
+bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
+ const TParseContext &parseContext,
+ const ShCompileOptions &compileOptions)
+{
+ mValidateASTOptions = {};
+
+ // Desktop GLSL shaders don't have precision, so don't expect them to be specified.
+ mValidateASTOptions.validatePrecision = !IsDesktopGLSpec(mShaderSpec);
+
+ if (!validateAST(root))
+ {
+ return false;
+ }
+
+ // For now, rewrite pixel local storage before collecting variables or any operations on images.
+ //
+ // TODO(anglebug.com/7279):
+ // Should this actually run after collecting variables?
+ // Do we need more introspection?
+ // Do we want to hide rewritten shader image uniforms from glGetActiveUniform?
+ if (hasPixelLocalStorageUniforms())
+ {
+ ASSERT(
+ IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_shader_pixel_local_storage));
+ if (!RewritePixelLocalStorage(this, root, getSymbolTable(), compileOptions,
+ getShaderVersion()))
+ {
+ mDiagnostics.globalError("internal compiler error translating pixel local storage");
+ return false;
+ }
+ }
+
+ // Disallow expressions deemed too complex.
+ if (compileOptions.limitExpressionComplexity && !limitExpressionComplexity(root))
+ {
+ return false;
+ }
+
+ if (shouldRunLoopAndIndexingValidation(compileOptions) &&
+ !ValidateLimitations(root, mShaderType, &mSymbolTable, &mDiagnostics))
+ {
+ return false;
+ }
+
+ if (shouldLimitTypeSizes() && !ValidateTypeSizeLimitations(root, &mSymbolTable, &mDiagnostics))
+ {
+ return false;
+ }
+
+ if (!ValidateFragColorAndFragData(mShaderType, mShaderVersion, mSymbolTable, &mDiagnostics))
+ {
+ return false;
+ }
+
+ // Fold expressions that could not be folded before validation that was done as a part of
+ // parsing.
+ if (!FoldExpressions(this, root, &mDiagnostics))
+ {
+ return false;
+ }
+ // Folding should only be able to generate warnings.
+ ASSERT(mDiagnostics.numErrors() == 0);
+
+ // Validate no barrier() after return before prunning it in |PruneNoOps()| below.
+ if (mShaderType == GL_TESS_CONTROL_SHADER && !ValidateBarrierFunctionCall(root, &mDiagnostics))
+ {
+ return false;
+ }
+
+ // We prune no-ops to work around driver bugs and to keep AST processing and output simple.
+ // The following kinds of no-ops are pruned:
+ // 1. Empty declarations "int;".
+ // 2. Literal statements: "1.0;". The ESSL output doesn't define a default precision
+ // for float, so float literal statements would end up with no precision which is
+ // invalid ESSL.
+ // 3. Any unreachable statement after a discard, return, break or continue.
+ // After this empty declarations are not allowed in the AST.
+ if (!PruneNoOps(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ mValidateASTOptions.validateNoStatementsAfterBranch = true;
+
+ // We need to generate globals early if we have non constant initializers enabled
+ bool initializeLocalsAndGlobals =
+ compileOptions.initializeUninitializedLocals && !IsOutputHLSL(getOutputType());
+ bool canUseLoopsToInitialize = !compileOptions.dontUseLoopsToInitializeVariables;
+ bool highPrecisionSupported = isHighPrecisionSupported();
+ bool enableNonConstantInitializers = IsExtensionEnabled(
+ mExtensionBehavior, TExtension::EXT_shader_non_constant_global_initializers);
+ // forceDeferGlobalInitializers is needed for MSL
+ // to convert a non-const global. For example:
+ //
+ // int someGlobal = 123;
+ //
+ // to
+ //
+ // int someGlobal;
+ // void main() {
+ // someGlobal = 123;
+ //
+ // This is because MSL doesn't allow statically initialized globals.
+ bool forceDeferGlobalInitializers = getOutputType() == SH_MSL_METAL_OUTPUT;
+
+ if (enableNonConstantInitializers &&
+ !DeferGlobalInitializers(this, root, initializeLocalsAndGlobals, canUseLoopsToInitialize,
+ highPrecisionSupported, forceDeferGlobalInitializers,
+ &mSymbolTable))
+ {
+ return false;
+ }
+
+ // Create the function DAG and check there is no recursion
+ if (!initCallDag(root))
+ {
+ return false;
+ }
+
+ if (compileOptions.limitCallStackDepth && !checkCallDepth())
+ {
+ return false;
+ }
+
+ // Checks which functions are used and if "main" exists
+ mFunctionMetadata.clear();
+ mFunctionMetadata.resize(mCallDag.size());
+ if (!tagUsedFunctions())
+ {
+ return false;
+ }
+
+ if (!pruneUnusedFunctions(root))
+ {
+ return false;
+ }
+
+ if (IsSpecWithFunctionBodyNewScope(mShaderSpec, mShaderVersion))
+ {
+ if (!ReplaceShadowingVariables(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ if (mShaderVersion >= 310 && !ValidateVaryingLocations(root, &mDiagnostics, mShaderType))
+ {
+ return false;
+ }
+
+ // anglebug.com/7484: The ESSL spec has a bug with images as function arguments. The recommended
+ // workaround is to inline functions that accept image arguments.
+ if (mShaderVersion >= 310 && !MonomorphizeUnsupportedFunctions(
+ this, root, &mSymbolTable, compileOptions,
+ UnsupportedFunctionArgsBitSet{UnsupportedFunctionArgs::Image}))
+ {
+ return false;
+ }
+
+ if (mShaderVersion >= 300 && mShaderType == GL_FRAGMENT_SHADER &&
+ !ValidateOutputs(root, getExtensionBehavior(), mResources.MaxDrawBuffers, &mDiagnostics))
+ {
+ return false;
+ }
+
+ if (parseContext.isExtensionEnabled(TExtension::EXT_clip_cull_distance))
+ {
+ if (!ValidateClipCullDistance(root, &mDiagnostics,
+ mResources.MaxCombinedClipAndCullDistances))
+ {
+ return false;
+ }
+ }
+
+ // Clamping uniform array bounds needs to happen after validateLimitations pass.
+ if (compileOptions.clampIndirectArrayBounds)
+ {
+ if (!ClampIndirectIndices(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.initializeBuiltinsForInstancedMultiview &&
+ (parseContext.isExtensionEnabled(TExtension::OVR_multiview2) ||
+ parseContext.isExtensionEnabled(TExtension::OVR_multiview)) &&
+ getShaderType() != GL_COMPUTE_SHADER)
+ {
+ if (!DeclareAndInitBuiltinsForInstancedMultiview(
+ this, root, mNumViews, mShaderType, compileOptions, mOutputType, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ // This pass might emit short circuits so keep it before the short circuit unfolding
+ if (compileOptions.rewriteDoWhileLoops)
+ {
+ if (!RewriteDoWhile(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.addAndTrueToLoopCondition)
+ {
+ if (!AddAndTrueToLoopCondition(this, root))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.unfoldShortCircuit)
+ {
+ if (!UnfoldShortCircuitAST(this, root))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.regenerateStructNames)
+ {
+ if (!RegenerateStructNames(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ if (mShaderType == GL_VERTEX_SHADER &&
+ IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_multi_draw))
+ {
+ if (compileOptions.emulateGLDrawID)
+ {
+ if (!EmulateGLDrawID(this, root, &mSymbolTable, &mUniforms,
+ shouldCollectVariables(compileOptions)))
+ {
+ return false;
+ }
+ }
+ }
+
+ if (mShaderType == GL_VERTEX_SHADER &&
+ IsExtensionEnabled(mExtensionBehavior,
+ TExtension::ANGLE_base_vertex_base_instance_shader_builtin))
+ {
+ if (compileOptions.emulateGLBaseVertexBaseInstance)
+ {
+ if (!EmulateGLBaseVertexBaseInstance(this, root, &mSymbolTable, &mUniforms,
+ shouldCollectVariables(compileOptions),
+ compileOptions.addBaseVertexToVertexID))
+ {
+ return false;
+ }
+ }
+ }
+
+ if (mShaderType == GL_FRAGMENT_SHADER && mShaderVersion == 100 && mResources.EXT_draw_buffers &&
+ mResources.MaxDrawBuffers > 1 &&
+ IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers))
+ {
+ if (!EmulateGLFragColorBroadcast(this, root, mResources.MaxDrawBuffers, &mOutputVariables,
+ &mSymbolTable, mShaderVersion))
+ {
+ return false;
+ }
+ }
+
+ int simplifyScalarized = compileOptions.scalarizeVecAndMatConstructorArgs
+ ? IntermNodePatternMatcher::kScalarizedVecOrMatConstructor
+ : 0;
+
+ // Split multi declarations and remove calls to array length().
+ // Note that SimplifyLoopConditions needs to be run before any other AST transformations
+ // that may need to generate new statements from loop conditions or loop expressions.
+ if (!SimplifyLoopConditions(this, root,
+ IntermNodePatternMatcher::kMultiDeclaration |
+ IntermNodePatternMatcher::kArrayLengthMethod |
+ simplifyScalarized,
+ &getSymbolTable()))
+ {
+ return false;
+ }
+
+ // Note that separate declarations need to be run before other AST transformations that
+ // generate new statements from expressions.
+ if (!SeparateDeclarations(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ mValidateASTOptions.validateMultiDeclarations = true;
+
+ if (!SplitSequenceOperator(this, root,
+ IntermNodePatternMatcher::kArrayLengthMethod | simplifyScalarized,
+ &getSymbolTable()))
+ {
+ return false;
+ }
+
+ if (!RemoveArrayLengthMethod(this, root))
+ {
+ return false;
+ }
+
+ if (!RemoveUnreferencedVariables(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+
+ // In case the last case inside a switch statement is a certain type of no-op, GLSL compilers in
+ // drivers may not accept it. In this case we clean up the dead code from the end of switch
+ // statements. This is also required because PruneNoOps or RemoveUnreferencedVariables may have
+ // left switch statements that only contained an empty declaration inside the final case in an
+ // invalid state. Relies on that PruneNoOps and RemoveUnreferencedVariables have already been
+ // run.
+ if (!PruneEmptyCases(this, root))
+ {
+ return false;
+ }
+
+ // Built-in function emulation needs to happen after validateLimitations pass.
+ GetGlobalPoolAllocator()->lock();
+ initBuiltInFunctionEmulator(&mBuiltInFunctionEmulator, compileOptions);
+ GetGlobalPoolAllocator()->unlock();
+ mBuiltInFunctionEmulator.markBuiltInFunctionsForEmulation(root);
+
+ if (compileOptions.scalarizeVecAndMatConstructorArgs)
+ {
+ if (!ScalarizeVecAndMatConstructorArgs(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.forceShaderPrecisionHighpToMediump)
+ {
+ if (!ForceShaderPrecisionToMediump(root, &mSymbolTable, mShaderType))
+ {
+ return false;
+ }
+ }
+
+ if (shouldCollectVariables(compileOptions))
+ {
+ ASSERT(!mVariablesCollected);
+ CollectVariables(root, &mAttributes, &mOutputVariables, &mUniforms, &mInputVaryings,
+ &mOutputVaryings, &mSharedVariables, &mUniformBlocks,
+ &mShaderStorageBlocks, mResources.HashFunction, &mSymbolTable, mShaderType,
+ mExtensionBehavior, mResources, mTessControlShaderOutputVertices);
+ collectInterfaceBlocks();
+ mVariablesCollected = true;
+ if (compileOptions.useUnusedStandardSharedBlocks)
+ {
+ if (!useAllMembersInUnusedStandardAndSharedBlocks(root))
+ {
+ return false;
+ }
+ }
+ if (compileOptions.enforcePackingRestrictions)
+ {
+ int maxUniformVectors = GetMaxUniformVectorsForShaderType(mShaderType, mResources);
+ // Returns true if, after applying the packing rules in the GLSL ES 1.00.17 spec
+ // Appendix A, section 7, the shader does not use too many uniforms.
+ if (!CheckVariablesInPackingLimits(maxUniformVectors, mUniforms))
+ {
+ mDiagnostics.globalError("too many uniforms");
+ return false;
+ }
+ }
+ bool needInitializeOutputVariables =
+ compileOptions.initOutputVariables && mShaderType != GL_COMPUTE_SHADER;
+ needInitializeOutputVariables |=
+ compileOptions.initFragmentOutputVariables && mShaderType == GL_FRAGMENT_SHADER;
+ if (needInitializeOutputVariables)
+ {
+ if (!initializeOutputVariables(root))
+ {
+ return false;
+ }
+ }
+ }
+
+ // Removing invariant declarations must be done after collecting variables.
+ // Otherwise, built-in invariant declarations don't apply.
+ if (RemoveInvariant(mShaderType, mShaderVersion, mOutputType, compileOptions))
+ {
+ if (!RemoveInvariantDeclaration(this, root))
+ {
+ return false;
+ }
+ }
+
+ // gl_Position is always written in compatibility output mode.
+ // It may have been already initialized among other output variables, in that case we don't
+ // need to initialize it twice.
+ if (mShaderType == GL_VERTEX_SHADER && !mGLPositionInitialized &&
+ (compileOptions.initGLPosition || mOutputType == SH_GLSL_COMPATIBILITY_OUTPUT))
+ {
+ if (!initializeGLPosition(root))
+ {
+ return false;
+ }
+ mGLPositionInitialized = true;
+ }
+
+ if (mShaderType == GL_VERTEX_SHADER && compileOptions.initGLPointSize)
+ {
+ sh::ShaderVariable var(GL_FLOAT);
+ var.name = "gl_PointSize";
+ if (!InitializeVariables(this, root, {var}, &mSymbolTable, mShaderVersion,
+ mExtensionBehavior, false, false))
+ {
+ return false;
+ }
+ }
+
+ // DeferGlobalInitializers needs to be run before other AST transformations that generate new
+ // statements from expressions. But it's fine to run DeferGlobalInitializers after the above
+ // SplitSequenceOperator and RemoveArrayLengthMethod since they only have an effect on the AST
+ // on ESSL >= 3.00, and the initializers that need to be deferred can only exist in ESSL < 3.00.
+ // Exception: if EXT_shader_non_constant_global_initializers is enabled, we must generate global
+ // initializers before we generate the DAG, since initializers may call functions which must not
+ // be optimized out
+ if (!enableNonConstantInitializers &&
+ !DeferGlobalInitializers(this, root, initializeLocalsAndGlobals, canUseLoopsToInitialize,
+ highPrecisionSupported, forceDeferGlobalInitializers,
+ &mSymbolTable))
+ {
+ return false;
+ }
+
+ if (initializeLocalsAndGlobals)
+ {
+ // Initialize uninitialized local variables.
+ // In some cases initializing can generate extra statements in the parent block, such as
+ // when initializing nameless structs or initializing arrays in ESSL 1.00. In that case
+ // we need to first simplify loop conditions. We've already separated declarations
+ // earlier, which is also required. If we don't follow the Appendix A limitations, loop
+ // init statements can declare arrays or nameless structs and have multiple
+ // declarations.
+
+ if (!shouldRunLoopAndIndexingValidation(compileOptions))
+ {
+ if (!SimplifyLoopConditions(this, root,
+ IntermNodePatternMatcher::kArrayDeclaration |
+ IntermNodePatternMatcher::kNamelessStructDeclaration,
+ &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (!InitializeUninitializedLocals(this, root, getShaderVersion(), canUseLoopsToInitialize,
+ highPrecisionSupported, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (getShaderType() == GL_VERTEX_SHADER && compileOptions.clampPointSize)
+ {
+ if (!ClampPointSize(this, root, mResources.MaxPointSize, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (getShaderType() == GL_FRAGMENT_SHADER && compileOptions.clampFragDepth)
+ {
+ if (!ClampFragDepth(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.rewriteRepeatedAssignToSwizzled)
+ {
+ if (!sh::RewriteRepeatedAssignToSwizzled(this, root))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.removeDynamicIndexingOfSwizzledVector)
+ {
+ if (!sh::RemoveDynamicIndexingOfSwizzledVector(this, root, &getSymbolTable(), nullptr))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool TCompiler::postParseChecks(const TParseContext &parseContext)
+{
+ std::stringstream errorMessage;
+
+ if (parseContext.getTreeRoot() == nullptr)
+ {
+ errorMessage << "Shader parsing failed (mTreeRoot == nullptr)";
+ }
+
+ for (TType *type : parseContext.getDeferredArrayTypesToSize())
+ {
+ errorMessage << "Unsized global array type: " << type->getBasicString();
+ }
+
+ if (!errorMessage.str().empty())
+ {
+ mDiagnostics.globalError(errorMessage.str().c_str());
+ return false;
+ }
+
+ return true;
+}
+
+bool TCompiler::compile(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptionsIn)
+{
+#if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
+ DumpFuzzerCase(shaderStrings, numStrings, mShaderType, mShaderSpec, mOutputType,
+ compileOptionsIn);
+#endif // defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
+
+ if (numStrings == 0)
+ return true;
+
+ ShCompileOptions compileOptions = compileOptionsIn;
+
+ // Apply key workarounds.
+ if (shouldFlattenPragmaStdglInvariantAll())
+ {
+ // This should be harmless to do in all cases, but for the moment, do it only conditionally.
+ compileOptions.flattenPragmaSTDGLInvariantAll = true;
+ }
+
+ TScopedPoolAllocator scopedAlloc(&allocator);
+ TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
+
+ if (root)
+ {
+ if (compileOptions.intermediateTree)
+ {
+ OutputTree(root, mInfoSink.info);
+ }
+
+ if (compileOptions.objectCode)
+ {
+ PerformanceDiagnostics perfDiagnostics(&mDiagnostics);
+ if (!translate(root, compileOptions, &perfDiagnostics))
+ {
+ return false;
+ }
+ }
+
+ if (mShaderType == GL_VERTEX_SHADER)
+ {
+ bool lookForDrawID =
+ IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_multi_draw) &&
+ compileOptions.emulateGLDrawID;
+ bool lookForBaseVertexBaseInstance =
+ IsExtensionEnabled(mExtensionBehavior,
+ TExtension::ANGLE_base_vertex_base_instance_shader_builtin) &&
+ compileOptions.emulateGLBaseVertexBaseInstance;
+
+ if (lookForDrawID || lookForBaseVertexBaseInstance)
+ {
+ for (auto &uniform : mUniforms)
+ {
+ if (lookForDrawID && uniform.name == "angle_DrawID" &&
+ uniform.mappedName == "angle_DrawID")
+ {
+ uniform.name = "gl_DrawID";
+ }
+ else if (lookForBaseVertexBaseInstance && uniform.name == "angle_BaseVertex" &&
+ uniform.mappedName == "angle_BaseVertex")
+ {
+ uniform.name = "gl_BaseVertex";
+ }
+ else if (lookForBaseVertexBaseInstance &&
+ uniform.name == "angle_BaseInstance" &&
+ uniform.mappedName == "angle_BaseInstance")
+ {
+ uniform.name = "gl_BaseInstance";
+ }
+ }
+ }
+ }
+
+ // The IntermNode tree doesn't need to be deleted here, since the
+ // memory will be freed in a big chunk by the PoolAllocator.
+ return true;
+ }
+ return false;
+}
+
+bool TCompiler::initBuiltInSymbolTable(const ShBuiltInResources &resources)
+{
+ if (resources.MaxDrawBuffers < 1)
+ {
+ return false;
+ }
+ if (resources.EXT_blend_func_extended && resources.MaxDualSourceDrawBuffers < 1)
+ {
+ return false;
+ }
+
+ mSymbolTable.initializeBuiltIns(mShaderType, mShaderSpec, resources);
+
+ return true;
+}
+
+void TCompiler::setResourceString()
+{
+ std::ostringstream strstream = sh::InitializeStream<std::ostringstream>();
+
+ // clang-format off
+ strstream << ":MaxVertexAttribs:" << mResources.MaxVertexAttribs
+ << ":MaxVertexUniformVectors:" << mResources.MaxVertexUniformVectors
+ << ":MaxVaryingVectors:" << mResources.MaxVaryingVectors
+ << ":MaxVertexTextureImageUnits:" << mResources.MaxVertexTextureImageUnits
+ << ":MaxCombinedTextureImageUnits:" << mResources.MaxCombinedTextureImageUnits
+ << ":MaxTextureImageUnits:" << mResources.MaxTextureImageUnits
+ << ":MaxFragmentUniformVectors:" << mResources.MaxFragmentUniformVectors
+ << ":MaxDrawBuffers:" << mResources.MaxDrawBuffers
+ << ":OES_standard_derivatives:" << mResources.OES_standard_derivatives
+ << ":OES_EGL_image_external:" << mResources.OES_EGL_image_external
+ << ":OES_EGL_image_external_essl3:" << mResources.OES_EGL_image_external_essl3
+ << ":NV_EGL_stream_consumer_external:" << mResources.NV_EGL_stream_consumer_external
+ << ":ARB_texture_rectangle:" << mResources.ARB_texture_rectangle
+ << ":EXT_draw_buffers:" << mResources.EXT_draw_buffers
+ << ":FragmentPrecisionHigh:" << mResources.FragmentPrecisionHigh
+ << ":MaxExpressionComplexity:" << mResources.MaxExpressionComplexity
+ << ":MaxCallStackDepth:" << mResources.MaxCallStackDepth
+ << ":MaxFunctionParameters:" << mResources.MaxFunctionParameters
+ << ":EXT_blend_func_extended:" << mResources.EXT_blend_func_extended
+ << ":EXT_frag_depth:" << mResources.EXT_frag_depth
+ << ":EXT_primitive_bounding_box:" << mResources.EXT_primitive_bounding_box
+ << ":OES_primitive_bounding_box:" << mResources.OES_primitive_bounding_box
+ << ":EXT_shader_texture_lod:" << mResources.EXT_shader_texture_lod
+ << ":EXT_shader_framebuffer_fetch:" << mResources.EXT_shader_framebuffer_fetch
+ << ":EXT_shader_framebuffer_fetch_non_coherent:" << mResources.EXT_shader_framebuffer_fetch_non_coherent
+ << ":NV_shader_framebuffer_fetch:" << mResources.NV_shader_framebuffer_fetch
+ << ":ARM_shader_framebuffer_fetch:" << mResources.ARM_shader_framebuffer_fetch
+ << ":OVR_multiview2:" << mResources.OVR_multiview2
+ << ":OVR_multiview:" << mResources.OVR_multiview
+ << ":EXT_YUV_target:" << mResources.EXT_YUV_target
+ << ":EXT_geometry_shader:" << mResources.EXT_geometry_shader
+ << ":OES_geometry_shader:" << mResources.OES_geometry_shader
+ << ":OES_shader_io_blocks:" << mResources.OES_shader_io_blocks
+ << ":EXT_shader_io_blocks:" << mResources.EXT_shader_io_blocks
+ << ":EXT_gpu_shader5:" << mResources.EXT_gpu_shader5
+ << ":OES_texture_3D:" << mResources.OES_texture_3D
+ << ":MaxVertexOutputVectors:" << mResources.MaxVertexOutputVectors
+ << ":MaxFragmentInputVectors:" << mResources.MaxFragmentInputVectors
+ << ":MinProgramTexelOffset:" << mResources.MinProgramTexelOffset
+ << ":MaxProgramTexelOffset:" << mResources.MaxProgramTexelOffset
+ << ":MaxDualSourceDrawBuffers:" << mResources.MaxDualSourceDrawBuffers
+ << ":MaxViewsOVR:" << mResources.MaxViewsOVR
+ << ":NV_draw_buffers:" << mResources.NV_draw_buffers
+ << ":ANGLE_multi_draw:" << mResources.ANGLE_multi_draw
+ << ":ANGLE_base_vertex_base_instance_shader_builtin:" << mResources.ANGLE_base_vertex_base_instance_shader_builtin
+ << ":APPLE_clip_distance:" << mResources.APPLE_clip_distance
+ << ":OES_texture_cube_map_array:" << mResources.OES_texture_cube_map_array
+ << ":EXT_texture_cube_map_array:" << mResources.EXT_texture_cube_map_array
+ << ":EXT_shadow_samplers:" << mResources.EXT_shadow_samplers
+ << ":OES_shader_multisample_interpolation:" << mResources.OES_shader_multisample_interpolation
+ << ":OES_shader_image_atomic:" << mResources.OES_shader_image_atomic
+ << ":EXT_tessellation_shader:" << mResources.EXT_tessellation_shader
+ << ":OES_texture_buffer:" << mResources.OES_texture_buffer
+ << ":EXT_texture_buffer:" << mResources.EXT_texture_buffer
+ << ":OES_sample_variables:" << mResources.OES_sample_variables
+ << ":EXT_clip_cull_distance:" << mResources.EXT_clip_cull_distance
+ << ":MinProgramTextureGatherOffset:" << mResources.MinProgramTextureGatherOffset
+ << ":MaxProgramTextureGatherOffset:" << mResources.MaxProgramTextureGatherOffset
+ << ":MaxImageUnits:" << mResources.MaxImageUnits
+ << ":MaxSamples:" << mResources.MaxSamples
+ << ":MaxVertexImageUniforms:" << mResources.MaxVertexImageUniforms
+ << ":MaxFragmentImageUniforms:" << mResources.MaxFragmentImageUniforms
+ << ":MaxComputeImageUniforms:" << mResources.MaxComputeImageUniforms
+ << ":MaxCombinedImageUniforms:" << mResources.MaxCombinedImageUniforms
+ << ":MaxCombinedShaderOutputResources:" << mResources.MaxCombinedShaderOutputResources
+ << ":MaxComputeWorkGroupCountX:" << mResources.MaxComputeWorkGroupCount[0]
+ << ":MaxComputeWorkGroupCountY:" << mResources.MaxComputeWorkGroupCount[1]
+ << ":MaxComputeWorkGroupCountZ:" << mResources.MaxComputeWorkGroupCount[2]
+ << ":MaxComputeWorkGroupSizeX:" << mResources.MaxComputeWorkGroupSize[0]
+ << ":MaxComputeWorkGroupSizeY:" << mResources.MaxComputeWorkGroupSize[1]
+ << ":MaxComputeWorkGroupSizeZ:" << mResources.MaxComputeWorkGroupSize[2]
+ << ":MaxComputeUniformComponents:" << mResources.MaxComputeUniformComponents
+ << ":MaxComputeTextureImageUnits:" << mResources.MaxComputeTextureImageUnits
+ << ":MaxComputeAtomicCounters:" << mResources.MaxComputeAtomicCounters
+ << ":MaxComputeAtomicCounterBuffers:" << mResources.MaxComputeAtomicCounterBuffers
+ << ":MaxVertexAtomicCounters:" << mResources.MaxVertexAtomicCounters
+ << ":MaxFragmentAtomicCounters:" << mResources.MaxFragmentAtomicCounters
+ << ":MaxCombinedAtomicCounters:" << mResources.MaxCombinedAtomicCounters
+ << ":MaxAtomicCounterBindings:" << mResources.MaxAtomicCounterBindings
+ << ":MaxVertexAtomicCounterBuffers:" << mResources.MaxVertexAtomicCounterBuffers
+ << ":MaxFragmentAtomicCounterBuffers:" << mResources.MaxFragmentAtomicCounterBuffers
+ << ":MaxCombinedAtomicCounterBuffers:" << mResources.MaxCombinedAtomicCounterBuffers
+ << ":MaxAtomicCounterBufferSize:" << mResources.MaxAtomicCounterBufferSize
+ << ":MaxGeometryUniformComponents:" << mResources.MaxGeometryUniformComponents
+ << ":MaxGeometryUniformBlocks:" << mResources.MaxGeometryUniformBlocks
+ << ":MaxGeometryInputComponents:" << mResources.MaxGeometryInputComponents
+ << ":MaxGeometryOutputComponents:" << mResources.MaxGeometryOutputComponents
+ << ":MaxGeometryOutputVertices:" << mResources.MaxGeometryOutputVertices
+ << ":MaxGeometryTotalOutputComponents:" << mResources.MaxGeometryTotalOutputComponents
+ << ":MaxGeometryTextureImageUnits:" << mResources.MaxGeometryTextureImageUnits
+ << ":MaxGeometryAtomicCounterBuffers:" << mResources.MaxGeometryAtomicCounterBuffers
+ << ":MaxGeometryAtomicCounters:" << mResources.MaxGeometryAtomicCounters
+ << ":MaxGeometryShaderStorageBlocks:" << mResources.MaxGeometryShaderStorageBlocks
+ << ":MaxGeometryShaderInvocations:" << mResources.MaxGeometryShaderInvocations
+ << ":MaxGeometryImageUniforms:" << mResources.MaxGeometryImageUniforms
+ << ":MaxClipDistances" << mResources.MaxClipDistances
+ << ":MaxCullDistances" << mResources.MaxCullDistances
+ << ":MaxCombinedClipAndCullDistances" << mResources.MaxCombinedClipAndCullDistances
+ << ":MaxTessControlInputComponents:" << mResources.MaxTessControlInputComponents
+ << ":MaxTessControlOutputComponents:" << mResources.MaxTessControlOutputComponents
+ << ":MaxTessControlTextureImageUnits:" << mResources.MaxTessControlTextureImageUnits
+ << ":MaxTessControlUniformComponents:" << mResources.MaxTessControlUniformComponents
+ << ":MaxTessControlTotalOutputComponents:" << mResources.MaxTessControlTotalOutputComponents
+ << ":MaxTessControlImageUniforms:" << mResources.MaxTessControlImageUniforms
+ << ":MaxTessControlAtomicCounters:" << mResources.MaxTessControlAtomicCounters
+ << ":MaxTessControlAtomicCounterBuffers:" << mResources.MaxTessControlAtomicCounterBuffers
+ << ":MaxTessPatchComponents:" << mResources.MaxTessPatchComponents
+ << ":MaxPatchVertices:" << mResources.MaxPatchVertices
+ << ":MaxTessGenLevel:" << mResources.MaxTessGenLevel
+ << ":MaxTessEvaluationInputComponents:" << mResources.MaxTessEvaluationInputComponents
+ << ":MaxTessEvaluationOutputComponents:" << mResources.MaxTessEvaluationOutputComponents
+ << ":MaxTessEvaluationTextureImageUnits:" << mResources.MaxTessEvaluationTextureImageUnits
+ << ":MaxTessEvaluationUniformComponents:" << mResources.MaxTessEvaluationUniformComponents
+ << ":MaxTessEvaluationImageUniforms:" << mResources.MaxTessEvaluationImageUniforms
+ << ":MaxTessEvaluationAtomicCounters:" << mResources.MaxTessEvaluationAtomicCounters
+ << ":MaxTessEvaluationAtomicCounterBuffers:" << mResources.MaxTessEvaluationAtomicCounterBuffers;
+ // clang-format on
+
+ mBuiltInResourcesString = strstream.str();
+}
+
+void TCompiler::collectInterfaceBlocks()
+{
+ ASSERT(mInterfaceBlocks.empty());
+ mInterfaceBlocks.reserve(mUniformBlocks.size() + mShaderStorageBlocks.size());
+ mInterfaceBlocks.insert(mInterfaceBlocks.end(), mUniformBlocks.begin(), mUniformBlocks.end());
+ mInterfaceBlocks.insert(mInterfaceBlocks.end(), mShaderStorageBlocks.begin(),
+ mShaderStorageBlocks.end());
+}
+
+void TCompiler::clearResults()
+{
+ mInfoSink.info.erase();
+ mInfoSink.obj.erase();
+ mInfoSink.debug.erase();
+ mDiagnostics.resetErrorCount();
+
+ mAttributes.clear();
+ mOutputVariables.clear();
+ mUniforms.clear();
+ mInputVaryings.clear();
+ mOutputVaryings.clear();
+ mSharedVariables.clear();
+ mInterfaceBlocks.clear();
+ mUniformBlocks.clear();
+ mShaderStorageBlocks.clear();
+ mVariablesCollected = false;
+ mGLPositionInitialized = false;
+
+ mNumViews = -1;
+
+ mGeometryShaderInputPrimitiveType = EptUndefined;
+ mGeometryShaderOutputPrimitiveType = EptUndefined;
+ mGeometryShaderInvocations = 0;
+ mGeometryShaderMaxVertices = -1;
+
+ mTessControlShaderOutputVertices = 0;
+ mTessEvaluationShaderInputPrimitiveType = EtetUndefined;
+ mTessEvaluationShaderInputVertexSpacingType = EtetUndefined;
+ mTessEvaluationShaderInputOrderingType = EtetUndefined;
+ mTessEvaluationShaderInputPointType = EtetUndefined;
+
+ mBuiltInFunctionEmulator.cleanup();
+
+ mNameMap.clear();
+
+ mSourcePath = nullptr;
+
+ mSymbolTable.clearCompilationResults();
+}
+
+bool TCompiler::initCallDag(TIntermNode *root)
+{
+ mCallDag.clear();
+
+ switch (mCallDag.init(root, &mDiagnostics))
+ {
+ case CallDAG::INITDAG_SUCCESS:
+ return true;
+ case CallDAG::INITDAG_RECURSION:
+ case CallDAG::INITDAG_UNDEFINED:
+ // Error message has already been written out.
+ ASSERT(mDiagnostics.numErrors() > 0);
+ return false;
+ }
+
+ UNREACHABLE();
+ return true;
+}
+
+bool TCompiler::checkCallDepth()
+{
+ std::vector<int> depths(mCallDag.size());
+
+ for (size_t i = 0; i < mCallDag.size(); i++)
+ {
+ int depth = 0;
+ const CallDAG::Record &record = mCallDag.getRecordFromIndex(i);
+
+ for (int calleeIndex : record.callees)
+ {
+ depth = std::max(depth, depths[calleeIndex] + 1);
+ }
+
+ depths[i] = depth;
+
+ if (depth >= mResources.MaxCallStackDepth)
+ {
+ // Trace back the function chain to have a meaningful info log.
+ std::stringstream errorStream = sh::InitializeStream<std::stringstream>();
+ errorStream << "Call stack too deep (larger than " << mResources.MaxCallStackDepth
+ << ") with the following call chain: "
+ << record.node->getFunction()->name();
+
+ int currentFunction = static_cast<int>(i);
+ int currentDepth = depth;
+
+ while (currentFunction != -1)
+ {
+ errorStream
+ << " -> "
+ << mCallDag.getRecordFromIndex(currentFunction).node->getFunction()->name();
+
+ int nextFunction = -1;
+ for (const int &calleeIndex : mCallDag.getRecordFromIndex(currentFunction).callees)
+ {
+ if (depths[calleeIndex] == currentDepth - 1)
+ {
+ currentDepth--;
+ nextFunction = calleeIndex;
+ }
+ }
+
+ currentFunction = nextFunction;
+ }
+
+ std::string errorStr = errorStream.str();
+ mDiagnostics.globalError(errorStr.c_str());
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool TCompiler::tagUsedFunctions()
+{
+ // Search from main, starting from the end of the DAG as it usually is the root.
+ for (size_t i = mCallDag.size(); i-- > 0;)
+ {
+ if (mCallDag.getRecordFromIndex(i).node->getFunction()->isMain())
+ {
+ internalTagUsedFunction(i);
+ return true;
+ }
+ }
+
+ mDiagnostics.globalError("Missing main()");
+ return false;
+}
+
+void TCompiler::internalTagUsedFunction(size_t index)
+{
+ if (mFunctionMetadata[index].used)
+ {
+ return;
+ }
+
+ mFunctionMetadata[index].used = true;
+
+ for (int calleeIndex : mCallDag.getRecordFromIndex(index).callees)
+ {
+ internalTagUsedFunction(calleeIndex);
+ }
+}
+
+bool TCompiler::pruneUnusedFunctions(TIntermBlock *root)
+{
+ TIntermSequence *sequence = root->getSequence();
+
+ size_t writeIndex = 0;
+ for (size_t readIndex = 0; readIndex < sequence->size(); ++readIndex)
+ {
+ TIntermNode *node = sequence->at(readIndex);
+
+ // Keep anything that's not unused.
+ const TFunction *function = nullptr;
+ const bool shouldPrune =
+ IsTopLevelNodeUnusedFunction(mCallDag, mFunctionMetadata, node, &function);
+ if (!shouldPrune)
+ {
+ (*sequence)[writeIndex++] = node;
+ continue;
+ }
+
+ // If a function is unused, it may have a struct declaration in its return value which
+ // shouldn't be pruned. In that case, replace the function definition with the struct
+ // definition.
+ ASSERT(function != nullptr);
+ const TType &returnType = function->getReturnType();
+ if (!returnType.isStructSpecifier())
+ {
+ continue;
+ }
+
+ TVariable *structVariable =
+ new TVariable(&mSymbolTable, kEmptyImmutableString, &returnType, SymbolType::Empty);
+ TIntermSymbol *structSymbol = new TIntermSymbol(structVariable);
+ TIntermDeclaration *structDeclaration = new TIntermDeclaration;
+ structDeclaration->appendDeclarator(structSymbol);
+
+ structSymbol->setLine(node->getLine());
+ structDeclaration->setLine(node->getLine());
+
+ (*sequence)[writeIndex++] = structDeclaration;
+ }
+
+ sequence->resize(writeIndex);
+
+ return validateAST(root);
+}
+
+bool TCompiler::limitExpressionComplexity(TIntermBlock *root)
+{
+ if (!IsASTDepthBelowLimit(root, mResources.MaxExpressionComplexity))
+ {
+ mDiagnostics.globalError("Expression too complex.");
+ return false;
+ }
+
+ if (!ValidateMaxParameters(root, mResources.MaxFunctionParameters))
+ {
+ mDiagnostics.globalError("Function has too many parameters.");
+ return false;
+ }
+
+ return true;
+}
+
+bool TCompiler::shouldCollectVariables(const ShCompileOptions &compileOptions)
+{
+ return compileOptions.variables;
+}
+
+bool TCompiler::wereVariablesCollected() const
+{
+ return mVariablesCollected;
+}
+
+bool TCompiler::initializeGLPosition(TIntermBlock *root)
+{
+ sh::ShaderVariable var(GL_FLOAT_VEC4);
+ var.name = "gl_Position";
+ return InitializeVariables(this, root, {var}, &mSymbolTable, mShaderVersion, mExtensionBehavior,
+ false, false);
+}
+
+bool TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root)
+{
+ sh::InterfaceBlockList list;
+
+ for (const sh::InterfaceBlock &block : mUniformBlocks)
+ {
+ if (!block.staticUse &&
+ (block.layout == sh::BLOCKLAYOUT_STD140 || block.layout == sh::BLOCKLAYOUT_SHARED))
+ {
+ list.push_back(block);
+ }
+ }
+
+ return sh::UseInterfaceBlockFields(this, root, list, mSymbolTable);
+}
+
+bool TCompiler::initializeOutputVariables(TIntermBlock *root)
+{
+ InitVariableList list;
+ list.reserve(mOutputVaryings.size());
+ if (mShaderType == GL_VERTEX_SHADER || mShaderType == GL_GEOMETRY_SHADER_EXT)
+ {
+ for (const sh::ShaderVariable &var : mOutputVaryings)
+ {
+ list.push_back(var);
+ if (var.name == "gl_Position")
+ {
+ ASSERT(!mGLPositionInitialized);
+ mGLPositionInitialized = true;
+ }
+ }
+ }
+ else
+ {
+ ASSERT(mShaderType == GL_FRAGMENT_SHADER);
+ for (const sh::ShaderVariable &var : mOutputVariables)
+ {
+ // in-out variables represent the context of the framebuffer
+ // when the draw call starts, so they have to be considered
+ // as already initialized.
+ if (!var.isFragmentInOut)
+ {
+ list.push_back(var);
+ }
+ }
+ }
+ return InitializeVariables(this, root, list, &mSymbolTable, mShaderVersion, mExtensionBehavior,
+ false, false);
+}
+
+const TExtensionBehavior &TCompiler::getExtensionBehavior() const
+{
+ return mExtensionBehavior;
+}
+
+const char *TCompiler::getSourcePath() const
+{
+ return mSourcePath;
+}
+
+const ShBuiltInResources &TCompiler::getResources() const
+{
+ return mResources;
+}
+
+const BuiltInFunctionEmulator &TCompiler::getBuiltInFunctionEmulator() const
+{
+ return mBuiltInFunctionEmulator;
+}
+
+bool TCompiler::isVaryingDefined(const char *varyingName)
+{
+ ASSERT(mVariablesCollected);
+ for (size_t ii = 0; ii < mInputVaryings.size(); ++ii)
+ {
+ if (mInputVaryings[ii].name == varyingName)
+ {
+ return true;
+ }
+ }
+ for (size_t ii = 0; ii < mOutputVaryings.size(); ++ii)
+ {
+ if (mOutputVaryings[ii].name == varyingName)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Compiler.h b/gfx/angle/checkout/src/compiler/translator/Compiler.h
new file mode 100644
index 0000000000..8a87d5ea24
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Compiler.h
@@ -0,0 +1,397 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_COMPILER_H_
+#define COMPILER_TRANSLATOR_COMPILER_H_
+
+//
+// Machine independent part of the compiler private objects
+// sent as ShHandle to the driver.
+//
+// This should not be included by driver code.
+//
+
+#include <GLSLANG/ShaderVars.h>
+
+#include "common/PackedEnums.h"
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/CallDAG.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/HashNames.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Pragma.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/ValidateAST.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TParseContext;
+#ifdef ANGLE_ENABLE_HLSL
+class TranslatorHLSL;
+#endif // ANGLE_ENABLE_HLSL
+#ifdef ANGLE_ENABLE_METAL
+class TranslatorMetalDirect;
+#endif // ANGLE_ENABLE_METAL
+
+using SpecConstUsageBits = angle::PackedEnumBitSet<vk::SpecConstUsage, uint32_t>;
+
+//
+// Helper function to check if the shader type is GLSL.
+//
+bool IsGLSL130OrNewer(ShShaderOutput output);
+bool IsGLSL420OrNewer(ShShaderOutput output);
+bool IsGLSL410OrOlder(ShShaderOutput output);
+
+//
+// Helper function to check if the invariant qualifier can be removed.
+//
+bool RemoveInvariant(sh::GLenum shaderType,
+ int shaderVersion,
+ ShShaderOutput outputType,
+ const ShCompileOptions &compileOptions);
+
+//
+// The base class used to back handles returned to the driver.
+//
+class TShHandleBase
+{
+ public:
+ TShHandleBase();
+ virtual ~TShHandleBase();
+ virtual TCompiler *getAsCompiler() { return 0; }
+#ifdef ANGLE_ENABLE_HLSL
+ virtual TranslatorHLSL *getAsTranslatorHLSL() { return 0; }
+#endif // ANGLE_ENABLE_HLSL
+#ifdef ANGLE_ENABLE_METAL
+ virtual TranslatorMetalDirect *getAsTranslatorMetalDirect() { return nullptr; }
+#endif // ANGLE_ENABLE_METAL
+
+ protected:
+ // Memory allocator. Allocates and tracks memory required by the compiler.
+ // Deallocates all memory when compiler is destructed.
+ angle::PoolAllocator allocator;
+};
+
+struct TFunctionMetadata
+{
+ bool used = false;
+};
+
+//
+// The base class for the machine dependent compiler to derive from
+// for managing object code from the compile.
+//
+class TCompiler : public TShHandleBase
+{
+ public:
+ TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
+ ~TCompiler() override;
+ TCompiler *getAsCompiler() override { return this; }
+
+ bool Init(const ShBuiltInResources &resources);
+
+ // compileTreeForTesting should be used only when tests require access to
+ // the AST. Users of this function need to manually manage the global pool
+ // allocator. Returns nullptr whenever there are compilation errors.
+ TIntermBlock *compileTreeForTesting(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions);
+
+ bool compile(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions);
+
+ // Get results of the last compilation.
+ int getShaderVersion() const { return mShaderVersion; }
+ TInfoSink &getInfoSink() { return mInfoSink; }
+
+ bool specifyEarlyFragmentTests() { return mEarlyFragmentTestsSpecified = true; }
+ bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
+ bool hasDiscard() const { return mHasDiscard; }
+ bool enablesPerSampleShading() const { return mEnablesPerSampleShading; }
+ SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
+
+ bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
+ const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
+ int getNumViews() const { return mNumViews; }
+
+ // Clears the results from the previous compilation.
+ void clearResults();
+
+ const std::vector<sh::ShaderVariable> &getAttributes() const { return mAttributes; }
+ const std::vector<sh::ShaderVariable> &getOutputVariables() const { return mOutputVariables; }
+ const std::vector<sh::ShaderVariable> &getUniforms() const { return mUniforms; }
+ const std::vector<sh::ShaderVariable> &getInputVaryings() const { return mInputVaryings; }
+ const std::vector<sh::ShaderVariable> &getOutputVaryings() const { return mOutputVaryings; }
+ const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return mInterfaceBlocks; }
+ const std::vector<sh::InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
+ const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks() const
+ {
+ return mShaderStorageBlocks;
+ }
+
+ ShHashFunction64 getHashFunction() const { return mResources.HashFunction; }
+ NameMap &getNameMap() { return mNameMap; }
+ TSymbolTable &getSymbolTable() { return mSymbolTable; }
+ ShShaderSpec getShaderSpec() const { return mShaderSpec; }
+ ShShaderOutput getOutputType() const { return mOutputType; }
+ ShBuiltInResources getBuiltInResources() const { return mResources; }
+ const std::string &getBuiltInResourcesString() const { return mBuiltInResourcesString; }
+
+ bool isHighPrecisionSupported() const;
+
+ bool shouldRunLoopAndIndexingValidation(const ShCompileOptions &compileOptions) const;
+ bool shouldLimitTypeSizes() const;
+
+ // Get the resources set by InitBuiltInSymbolTable
+ const ShBuiltInResources &getResources() const;
+
+ const TPragma &getPragma() const { return mPragma; }
+
+ int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
+ int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; }
+ TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
+ {
+ return mGeometryShaderInputPrimitiveType;
+ }
+ TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
+ {
+ return mGeometryShaderOutputPrimitiveType;
+ }
+
+ unsigned int getStructSize(const ShaderVariable &var) const;
+
+ int getTessControlShaderOutputVertices() const { return mTessControlShaderOutputVertices; }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputPrimitiveType() const
+ {
+ return mTessEvaluationShaderInputPrimitiveType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputVertexSpacingType() const
+ {
+ return mTessEvaluationShaderInputVertexSpacingType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputOrderingType() const
+ {
+ return mTessEvaluationShaderInputOrderingType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputPointType() const
+ {
+ return mTessEvaluationShaderInputPointType;
+ }
+
+ bool hasAnyPreciseType() const { return mHasAnyPreciseType; }
+
+ AdvancedBlendEquations getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
+
+ bool hasPixelLocalStorageUniforms() const { return mHasPixelLocalStorageUniforms; }
+
+ unsigned int getSharedMemorySize() const;
+
+ sh::GLenum getShaderType() const { return mShaderType; }
+
+ // Validate the AST and produce errors if it is inconsistent.
+ bool validateAST(TIntermNode *root);
+ // Some transformations may need to temporarily disable validation until they are complete. A
+ // set of disable/enable helpers are used for this purpose.
+ bool disableValidateFunctionCall();
+ void restoreValidateFunctionCall(bool enable);
+ bool disableValidateVariableReferences();
+ void restoreValidateVariableReferences(bool enable);
+ // When the AST is post-processed (such as to determine precise-ness of intermediate nodes),
+ // it's expected to no longer transform.
+ void enableValidateNoMoreTransformations();
+
+ protected:
+ // Add emulated functions to the built-in function emulator.
+ virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
+ const ShCompileOptions &compileOptions)
+ {}
+ // Translate to object code. May generate performance warnings through the diagnostics.
+ [[nodiscard]] virtual bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) = 0;
+ // Get built-in extensions with default behavior.
+ const TExtensionBehavior &getExtensionBehavior() const;
+ const char *getSourcePath() const;
+ // Relies on collectVariables having been called.
+ bool isVaryingDefined(const char *varyingName);
+
+ const BuiltInFunctionEmulator &getBuiltInFunctionEmulator() const;
+
+ virtual bool shouldFlattenPragmaStdglInvariantAll() = 0;
+ virtual bool shouldCollectVariables(const ShCompileOptions &compileOptions);
+
+ bool wereVariablesCollected() const;
+ std::vector<sh::ShaderVariable> mAttributes;
+ std::vector<sh::ShaderVariable> mOutputVariables;
+ std::vector<sh::ShaderVariable> mUniforms;
+ std::vector<sh::ShaderVariable> mInputVaryings;
+ std::vector<sh::ShaderVariable> mOutputVaryings;
+ std::vector<sh::ShaderVariable> mSharedVariables;
+ std::vector<sh::InterfaceBlock> mInterfaceBlocks;
+ std::vector<sh::InterfaceBlock> mUniformBlocks;
+ std::vector<sh::InterfaceBlock> mShaderStorageBlocks;
+
+ // Track what should be validated given passes currently applied.
+ ValidateASTOptions mValidateASTOptions;
+
+ // Specialization constant usage bits
+ SpecConstUsageBits mSpecConstUsageBits;
+
+ private:
+ // Initialize symbol-table with built-in symbols.
+ bool initBuiltInSymbolTable(const ShBuiltInResources &resources);
+ // Compute the string representation of the built-in resources
+ void setResourceString();
+ // Return false if the call depth is exceeded.
+ bool checkCallDepth();
+ // Insert statements to reference all members in unused uniform blocks with standard and shared
+ // layout. This is to work around a Mac driver that treats unused standard/shared
+ // uniform blocks as inactive.
+ [[nodiscard]] bool useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root);
+ // Insert statements to initialize output variables in the beginning of main().
+ // This is to avoid undefined behaviors.
+ [[nodiscard]] bool initializeOutputVariables(TIntermBlock *root);
+ // Insert gl_Position = vec4(0,0,0,0) to the beginning of main().
+ // It is to work around a Linux driver bug where missing this causes compile failure
+ // while spec says it is allowed.
+ // This function should only be applied to vertex shaders.
+ [[nodiscard]] bool initializeGLPosition(TIntermBlock *root);
+ // Return true if the maximum expression complexity is below the limit.
+ bool limitExpressionComplexity(TIntermBlock *root);
+ // Creates the function call DAG for further analysis, returning false if there is a recursion
+ bool initCallDag(TIntermNode *root);
+ // Return false if "main" doesn't exist
+ bool tagUsedFunctions();
+ void internalTagUsedFunction(size_t index);
+
+ void collectInterfaceBlocks();
+
+ bool mVariablesCollected;
+
+ bool mGLPositionInitialized;
+
+ // Removes unused function declarations and prototypes from the AST
+ bool pruneUnusedFunctions(TIntermBlock *root);
+
+ TIntermBlock *compileTreeImpl(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions);
+
+ // Fetches and stores shader metadata that is not stored within the AST itself, such as shader
+ // version.
+ void setASTMetadata(const TParseContext &parseContext);
+
+ // Check if shader version meets the requirement.
+ bool checkShaderVersion(TParseContext *parseContext);
+
+ // Does checks that need to be run after parsing is complete and returns true if they pass.
+ bool checkAndSimplifyAST(TIntermBlock *root,
+ const TParseContext &parseContext,
+ const ShCompileOptions &compileOptions);
+
+ bool postParseChecks(const TParseContext &parseContext);
+
+ sh::GLenum mShaderType;
+ ShShaderSpec mShaderSpec;
+ ShShaderOutput mOutputType;
+
+ CallDAG mCallDag;
+ std::vector<TFunctionMetadata> mFunctionMetadata;
+
+ ShBuiltInResources mResources;
+ std::string mBuiltInResourcesString;
+
+ // Built-in symbol table for the given language, spec, and resources.
+ // It is preserved from compile-to-compile.
+ TSymbolTable mSymbolTable;
+ // Built-in extensions with default behavior.
+ TExtensionBehavior mExtensionBehavior;
+
+ BuiltInFunctionEmulator mBuiltInFunctionEmulator;
+
+ // Results of compilation.
+ int mShaderVersion;
+ TInfoSink mInfoSink; // Output sink.
+ TDiagnostics mDiagnostics;
+ const char *mSourcePath; // Path of source file or NULL
+
+ // Fragment shader early fragment tests
+ bool mEarlyFragmentTestsSpecified;
+
+ // Fragment shader has the discard instruction
+ bool mHasDiscard;
+
+ // Whether per-sample shading is enabled by the shader. In OpenGL, this keyword should
+ // implicitly trigger per-sample shading without the API enabling it.
+ bool mEnablesPerSampleShading;
+
+ // compute shader local group size
+ bool mComputeShaderLocalSizeDeclared;
+ sh::WorkGroupSize mComputeShaderLocalSize;
+
+ // GL_OVR_multiview num_views.
+ int mNumViews;
+
+ // geometry shader parameters.
+ int mGeometryShaderMaxVertices;
+ int mGeometryShaderInvocations;
+ TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
+ TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
+
+ // tesssellation shader parameters
+ int mTessControlShaderOutputVertices;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputPrimitiveType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputVertexSpacingType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputOrderingType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputPointType;
+
+ bool mHasAnyPreciseType;
+
+ // advanced blend equation parameters
+ AdvancedBlendEquations mAdvancedBlendEquations;
+
+ // ANGLE_shader_pixel_local_storage.
+ bool mHasPixelLocalStorageUniforms;
+
+ // name hashing.
+ NameMap mNameMap;
+
+ TPragma mPragma;
+
+ ShCompileOptions mCompileOptions;
+};
+
+//
+// This is the interface between the machine independent code
+// and the machine dependent code.
+//
+// The machine dependent code should derive from the classes
+// above. Then Construct*() and Delete*() will create and
+// destroy the machine dependent objects, which contain the
+// above machine independent information.
+//
+TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
+void DeleteCompiler(TCompiler *);
+
+struct ShaderDumpHeader
+{
+ uint32_t type;
+ uint32_t spec;
+ uint32_t output;
+ uint8_t basicCompileOptions[32];
+ uint8_t metalCompileOptions[32];
+ uint8_t plsCompileOptions[32];
+ uint8_t padding[20];
+};
+static_assert(sizeof(ShaderDumpHeader) == 128);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_COMPILER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ConstantUnion.cpp b/gfx/angle/checkout/src/compiler/translator/ConstantUnion.cpp
new file mode 100644
index 0000000000..99af1c4f6c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ConstantUnion.cpp
@@ -0,0 +1,803 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ConstantUnion: Constant folding helper class.
+
+#include "compiler/translator/ConstantUnion.h"
+
+#include "common/mathutil.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+float CheckedSum(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
+{
+ float result = lhs + rhs;
+ if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
+ {
+ diag->warning(line, "Constant folded undefined addition generated NaN", "+");
+ }
+ else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
+ {
+ diag->warning(line, "Constant folded addition overflowed to infinity", "+");
+ }
+ return result;
+}
+
+float CheckedDiff(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
+{
+ float result = lhs - rhs;
+ if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
+ {
+ diag->warning(line, "Constant folded undefined subtraction generated NaN", "-");
+ }
+ else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
+ {
+ diag->warning(line, "Constant folded subtraction overflowed to infinity", "-");
+ }
+ return result;
+}
+
+float CheckedMul(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
+{
+ float result = lhs * rhs;
+ if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
+ {
+ diag->warning(line, "Constant folded undefined multiplication generated NaN", "*");
+ }
+ else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
+ {
+ diag->warning(line, "Constant folded multiplication overflowed to infinity", "*");
+ }
+ return result;
+}
+
+bool IsValidShiftOffset(const TConstantUnion &rhs)
+{
+ return (rhs.getType() == EbtInt && (rhs.getIConst() >= 0 && rhs.getIConst() <= 31)) ||
+ (rhs.getType() == EbtUInt && rhs.getUConst() <= 31u);
+}
+
+} // anonymous namespace
+
+TConstantUnion::TConstantUnion() : iConst(0), type(EbtVoid) {}
+
+TConstantUnion::TConstantUnion(int i) : iConst(i), type(EbtInt) {}
+
+TConstantUnion::TConstantUnion(unsigned int u) : uConst(u), type(EbtUInt) {}
+
+TConstantUnion::TConstantUnion(float f) : fConst(f), type(EbtFloat) {}
+
+TConstantUnion::TConstantUnion(bool b) : bConst(b), type(EbtBool) {}
+
+int TConstantUnion::getIConst() const
+{
+ ASSERT(type == EbtInt);
+ return iConst;
+}
+
+unsigned int TConstantUnion::getUConst() const
+{
+ ASSERT(type == EbtUInt);
+ return uConst;
+}
+
+float TConstantUnion::getFConst() const
+{
+ switch (type)
+ {
+ case EbtInt:
+ return static_cast<float>(iConst);
+ case EbtUInt:
+ return static_cast<float>(uConst);
+ default:
+ ASSERT(type == EbtFloat);
+ return fConst;
+ }
+}
+
+bool TConstantUnion::getBConst() const
+{
+ ASSERT(type == EbtBool);
+ return bConst;
+}
+
+bool TConstantUnion::isZero() const
+{
+ switch (type)
+ {
+ case EbtInt:
+ return getIConst() == 0;
+ case EbtUInt:
+ return getUConst() == 0;
+ case EbtFloat:
+ return getFConst() == 0.0f;
+ case EbtBool:
+ return getBConst() == false;
+ default:
+ return false;
+ }
+}
+
+TYuvCscStandardEXT TConstantUnion::getYuvCscStandardEXTConst() const
+{
+ ASSERT(type == EbtYuvCscStandardEXT);
+ return yuvCscStandardEXTConst;
+}
+
+bool TConstantUnion::cast(TBasicType newType, const TConstantUnion &constant)
+{
+ switch (newType)
+ {
+ case EbtFloat:
+ switch (constant.type)
+ {
+ case EbtInt:
+ setFConst(static_cast<float>(constant.getIConst()));
+ break;
+ case EbtUInt:
+ setFConst(static_cast<float>(constant.getUConst()));
+ break;
+ case EbtBool:
+ setFConst(static_cast<float>(constant.getBConst()));
+ break;
+ case EbtFloat:
+ setFConst(static_cast<float>(constant.getFConst()));
+ break;
+ default:
+ return false;
+ }
+ break;
+ case EbtInt:
+ switch (constant.type)
+ {
+ case EbtInt:
+ setIConst(static_cast<int>(constant.getIConst()));
+ break;
+ case EbtUInt:
+ setIConst(static_cast<int>(constant.getUConst()));
+ break;
+ case EbtBool:
+ setIConst(static_cast<int>(constant.getBConst()));
+ break;
+ case EbtFloat:
+ setIConst(static_cast<int>(constant.getFConst()));
+ break;
+ default:
+ return false;
+ }
+ break;
+ case EbtUInt:
+ switch (constant.type)
+ {
+ case EbtInt:
+ setUConst(static_cast<unsigned int>(constant.getIConst()));
+ break;
+ case EbtUInt:
+ setUConst(static_cast<unsigned int>(constant.getUConst()));
+ break;
+ case EbtBool:
+ setUConst(static_cast<unsigned int>(constant.getBConst()));
+ break;
+ case EbtFloat:
+ if (constant.getFConst() < 0.0f)
+ {
+ // Avoid undefined behavior in C++ by first casting to signed int.
+ setUConst(
+ static_cast<unsigned int>(static_cast<int>(constant.getFConst())));
+ }
+ else
+ {
+ setUConst(static_cast<unsigned int>(constant.getFConst()));
+ }
+ break;
+ default:
+ return false;
+ }
+ break;
+ case EbtBool:
+ switch (constant.type)
+ {
+ case EbtInt:
+ setBConst(constant.getIConst() != 0);
+ break;
+ case EbtUInt:
+ setBConst(constant.getUConst() != 0);
+ break;
+ case EbtBool:
+ setBConst(constant.getBConst());
+ break;
+ case EbtFloat:
+ setBConst(constant.getFConst() != 0.0f);
+ break;
+ default:
+ return false;
+ }
+ break;
+ case EbtStruct: // Struct fields don't get cast
+ switch (constant.type)
+ {
+ case EbtInt:
+ setIConst(constant.getIConst());
+ break;
+ case EbtUInt:
+ setUConst(constant.getUConst());
+ break;
+ case EbtBool:
+ setBConst(constant.getBConst());
+ break;
+ case EbtFloat:
+ setFConst(constant.getFConst());
+ break;
+ default:
+ return false;
+ }
+ break;
+ case EbtYuvCscStandardEXT:
+ switch (constant.type)
+ {
+ case EbtYuvCscStandardEXT:
+ setYuvCscStandardEXTConst(constant.getYuvCscStandardEXTConst());
+ break;
+ default:
+ return false;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool TConstantUnion::operator==(const int i) const
+{
+ switch (type)
+ {
+ case EbtFloat:
+ return static_cast<float>(i) == fConst;
+ default:
+ return i == iConst;
+ }
+}
+
+bool TConstantUnion::operator==(const unsigned int u) const
+{
+ switch (type)
+ {
+ case EbtFloat:
+ return static_cast<float>(u) == fConst;
+ default:
+ return u == uConst;
+ }
+}
+
+bool TConstantUnion::operator==(const float f) const
+{
+ switch (type)
+ {
+ case EbtInt:
+ return f == static_cast<float>(iConst);
+ case EbtUInt:
+ return f == static_cast<float>(uConst);
+ default:
+ return f == fConst;
+ }
+}
+
+bool TConstantUnion::operator==(const bool b) const
+{
+ return b == bConst;
+}
+
+bool TConstantUnion::operator==(const TYuvCscStandardEXT s) const
+{
+ return s == yuvCscStandardEXTConst;
+}
+
+bool TConstantUnion::operator==(const TConstantUnion &constant) const
+{
+ ImplicitTypeConversion conversion = GetConversion(constant.type, type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ switch (type)
+ {
+ case EbtInt:
+ return constant.iConst == iConst;
+ case EbtUInt:
+ return constant.uConst == uConst;
+ case EbtFloat:
+ return constant.fConst == fConst;
+ case EbtBool:
+ return constant.bConst == bConst;
+ case EbtYuvCscStandardEXT:
+ return constant.yuvCscStandardEXTConst == yuvCscStandardEXTConst;
+ default:
+ return false;
+ }
+ }
+ else if (conversion == ImplicitTypeConversion::Invalid)
+ {
+ return false;
+ }
+ else
+ {
+ return constant.getFConst() == getFConst();
+ }
+}
+
+bool TConstantUnion::operator!=(const int i) const
+{
+ return !operator==(i);
+}
+
+bool TConstantUnion::operator!=(const unsigned int u) const
+{
+ return !operator==(u);
+}
+
+bool TConstantUnion::operator!=(const float f) const
+{
+ return !operator==(f);
+}
+
+bool TConstantUnion::operator!=(const bool b) const
+{
+ return !operator==(b);
+}
+
+bool TConstantUnion::operator!=(const TYuvCscStandardEXT s) const
+{
+ return !operator==(s);
+}
+
+bool TConstantUnion::operator!=(const TConstantUnion &constant) const
+{
+ return !operator==(constant);
+}
+
+bool TConstantUnion::operator>(const TConstantUnion &constant) const
+{
+
+ ImplicitTypeConversion conversion = GetConversion(constant.type, type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ switch (type)
+ {
+ case EbtInt:
+ return iConst > constant.iConst;
+ case EbtUInt:
+ return uConst > constant.uConst;
+ case EbtFloat:
+ return fConst > constant.fConst;
+ default:
+ return false; // Invalid operation, handled at semantic analysis
+ }
+ }
+ else
+ {
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ return getFConst() > constant.getFConst();
+ }
+}
+
+bool TConstantUnion::operator<(const TConstantUnion &constant) const
+{
+ ImplicitTypeConversion conversion = GetConversion(constant.type, type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ switch (type)
+ {
+ case EbtInt:
+ return iConst < constant.iConst;
+ case EbtUInt:
+ return uConst < constant.uConst;
+ case EbtFloat:
+ return fConst < constant.fConst;
+ default:
+ return false; // Invalid operation, handled at semantic analysis
+ }
+ }
+ else
+ {
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ return getFConst() < constant.getFConst();
+ }
+}
+
+// static
+TConstantUnion TConstantUnion::add(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line)
+{
+ TConstantUnion returnValue;
+
+ ImplicitTypeConversion conversion = GetConversion(lhs.type, rhs.type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ switch (lhs.type)
+ {
+ case EbtInt:
+ returnValue.setIConst(gl::WrappingSum<int>(lhs.iConst, rhs.iConst));
+ break;
+ case EbtUInt:
+ returnValue.setUConst(gl::WrappingSum<unsigned int>(lhs.uConst, rhs.uConst));
+ break;
+ case EbtFloat:
+ returnValue.setFConst(CheckedSum(lhs.fConst, rhs.fConst, diag, line));
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ returnValue.setFConst(CheckedSum(lhs.getFConst(), rhs.getFConst(), diag, line));
+ }
+
+ return returnValue;
+}
+
+// static
+TConstantUnion TConstantUnion::sub(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line)
+{
+ TConstantUnion returnValue;
+
+ ImplicitTypeConversion conversion = GetConversion(lhs.type, rhs.type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ switch (lhs.type)
+ {
+ case EbtInt:
+ returnValue.setIConst(gl::WrappingDiff<int>(lhs.iConst, rhs.iConst));
+ break;
+ case EbtUInt:
+ returnValue.setUConst(gl::WrappingDiff<unsigned int>(lhs.uConst, rhs.uConst));
+ break;
+ case EbtFloat:
+ returnValue.setFConst(CheckedDiff(lhs.fConst, rhs.fConst, diag, line));
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ returnValue.setFConst(CheckedDiff(lhs.getFConst(), rhs.getFConst(), diag, line));
+ }
+
+ return returnValue;
+}
+
+// static
+TConstantUnion TConstantUnion::mul(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line)
+{
+ TConstantUnion returnValue;
+
+ ImplicitTypeConversion conversion = GetConversion(lhs.type, rhs.type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ switch (lhs.type)
+ {
+ case EbtInt:
+ returnValue.setIConst(gl::WrappingMul(lhs.iConst, rhs.iConst));
+ break;
+ case EbtUInt:
+ // Unsigned integer math in C++ is defined to be done in modulo 2^n, so we rely
+ // on that to implement wrapping multiplication.
+ returnValue.setUConst(lhs.uConst * rhs.uConst);
+ break;
+ case EbtFloat:
+ returnValue.setFConst(CheckedMul(lhs.fConst, rhs.fConst, diag, line));
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ returnValue.setFConst(CheckedMul(lhs.getFConst(), rhs.getFConst(), diag, line));
+ }
+
+ return returnValue;
+}
+
+TConstantUnion TConstantUnion::operator%(const TConstantUnion &constant) const
+{
+ TConstantUnion returnValue;
+ ASSERT(type == constant.type);
+ switch (type)
+ {
+ case EbtInt:
+ returnValue.setIConst(iConst % constant.iConst);
+ break;
+ case EbtUInt:
+ returnValue.setUConst(uConst % constant.uConst);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return returnValue;
+}
+
+// static
+TConstantUnion TConstantUnion::rshift(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line)
+{
+ TConstantUnion returnValue;
+ ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
+ ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
+ if (!IsValidShiftOffset(rhs))
+ {
+ diag->warning(line, "Undefined shift (operand out of range)", ">>");
+ switch (lhs.type)
+ {
+ case EbtInt:
+ returnValue.setIConst(0);
+ break;
+ case EbtUInt:
+ returnValue.setUConst(0u);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ return returnValue;
+ }
+
+ switch (lhs.type)
+ {
+ case EbtInt:
+ {
+ unsigned int shiftOffset = 0;
+ switch (rhs.type)
+ {
+ case EbtInt:
+ shiftOffset = static_cast<unsigned int>(rhs.iConst);
+ break;
+ case EbtUInt:
+ shiftOffset = rhs.uConst;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ if (shiftOffset > 0)
+ {
+ // ESSL 3.00.6 section 5.9: "If E1 is a signed integer, the right-shift will extend
+ // the sign bit." In C++ shifting negative integers is undefined, so we implement
+ // extending the sign bit manually.
+ int lhsSafe = lhs.iConst;
+ if (lhsSafe == std::numeric_limits<int>::min())
+ {
+ // The min integer needs special treatment because only bit it has set is the
+ // sign bit, which we clear later to implement safe right shift of negative
+ // numbers.
+ lhsSafe = -0x40000000;
+ --shiftOffset;
+ }
+ if (shiftOffset > 0)
+ {
+ bool extendSignBit = false;
+ if (lhsSafe < 0)
+ {
+ extendSignBit = true;
+ // Clear the sign bit so that bitshift right is defined in C++.
+ lhsSafe &= 0x7fffffff;
+ ASSERT(lhsSafe > 0);
+ }
+ returnValue.setIConst(lhsSafe >> shiftOffset);
+
+ // Manually fill in the extended sign bit if necessary.
+ if (extendSignBit)
+ {
+ int extendedSignBit = static_cast<int>(0xffffffffu << (31 - shiftOffset));
+ returnValue.setIConst(returnValue.getIConst() | extendedSignBit);
+ }
+ }
+ else
+ {
+ returnValue.setIConst(lhsSafe);
+ }
+ }
+ else
+ {
+ returnValue.setIConst(lhs.iConst);
+ }
+ break;
+ }
+ case EbtUInt:
+ switch (rhs.type)
+ {
+ case EbtInt:
+ returnValue.setUConst(lhs.uConst >> rhs.iConst);
+ break;
+ case EbtUInt:
+ returnValue.setUConst(lhs.uConst >> rhs.uConst);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+ return returnValue;
+}
+
+// static
+TConstantUnion TConstantUnion::lshift(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line)
+{
+ TConstantUnion returnValue;
+ ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
+ ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
+ if (!IsValidShiftOffset(rhs))
+ {
+ diag->warning(line, "Undefined shift (operand out of range)", "<<");
+ switch (lhs.type)
+ {
+ case EbtInt:
+ returnValue.setIConst(0);
+ break;
+ case EbtUInt:
+ returnValue.setUConst(0u);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ return returnValue;
+ }
+
+ switch (lhs.type)
+ {
+ case EbtInt:
+ switch (rhs.type)
+ {
+ // Cast to unsigned integer before shifting, since ESSL 3.00.6 section 5.9 says that
+ // lhs is "interpreted as a bit pattern". This also avoids the possibility of signed
+ // integer overflow or undefined shift of a negative integer.
+ case EbtInt:
+ returnValue.setIConst(
+ static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.iConst));
+ break;
+ case EbtUInt:
+ returnValue.setIConst(
+ static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.uConst));
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+
+ case EbtUInt:
+ switch (rhs.type)
+ {
+ case EbtInt:
+ returnValue.setUConst(lhs.uConst << rhs.iConst);
+ break;
+ case EbtUInt:
+ returnValue.setUConst(lhs.uConst << rhs.uConst);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+ return returnValue;
+}
+
+TConstantUnion TConstantUnion::operator&(const TConstantUnion &constant) const
+{
+ TConstantUnion returnValue;
+ ASSERT(constant.type == EbtInt || constant.type == EbtUInt);
+ switch (type)
+ {
+ case EbtInt:
+ returnValue.setIConst(iConst & constant.iConst);
+ break;
+ case EbtUInt:
+ returnValue.setUConst(uConst & constant.uConst);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return returnValue;
+}
+
+TConstantUnion TConstantUnion::operator|(const TConstantUnion &constant) const
+{
+ TConstantUnion returnValue;
+ ASSERT(type == constant.type);
+ switch (type)
+ {
+ case EbtInt:
+ returnValue.setIConst(iConst | constant.iConst);
+ break;
+ case EbtUInt:
+ returnValue.setUConst(uConst | constant.uConst);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return returnValue;
+}
+
+TConstantUnion TConstantUnion::operator^(const TConstantUnion &constant) const
+{
+ TConstantUnion returnValue;
+ ASSERT(type == constant.type);
+ switch (type)
+ {
+ case EbtInt:
+ returnValue.setIConst(iConst ^ constant.iConst);
+ break;
+ case EbtUInt:
+ returnValue.setUConst(uConst ^ constant.uConst);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return returnValue;
+}
+
+TConstantUnion TConstantUnion::operator&&(const TConstantUnion &constant) const
+{
+ TConstantUnion returnValue;
+ ASSERT(type == constant.type);
+ switch (type)
+ {
+ case EbtBool:
+ returnValue.setBConst(bConst && constant.bConst);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return returnValue;
+}
+
+TConstantUnion TConstantUnion::operator||(const TConstantUnion &constant) const
+{
+ TConstantUnion returnValue;
+ ASSERT(type == constant.type);
+ switch (type)
+ {
+ case EbtBool:
+ returnValue.setBConst(bConst || constant.bConst);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return returnValue;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ConstantUnion.h b/gfx/angle/checkout/src/compiler/translator/ConstantUnion.h
new file mode 100644
index 0000000000..df53857dd3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ConstantUnion.h
@@ -0,0 +1,122 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_CONSTANTUNION_H_
+#define COMPILER_TRANSLATOR_CONSTANTUNION_H_
+
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+class TDiagnostics;
+
+class TConstantUnion
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TConstantUnion();
+ TConstantUnion(int i);
+ TConstantUnion(unsigned int u);
+ TConstantUnion(float f);
+ TConstantUnion(bool b);
+
+ bool cast(TBasicType newType, const TConstantUnion &constant);
+
+ void setIConst(int i)
+ {
+ iConst = i;
+ type = EbtInt;
+ }
+ void setUConst(unsigned int u)
+ {
+ uConst = u;
+ type = EbtUInt;
+ }
+ void setFConst(float f)
+ {
+ fConst = f;
+ type = EbtFloat;
+ }
+ void setBConst(bool b)
+ {
+ bConst = b;
+ type = EbtBool;
+ }
+
+ void setYuvCscStandardEXTConst(TYuvCscStandardEXT s)
+ {
+ yuvCscStandardEXTConst = s;
+ type = EbtYuvCscStandardEXT;
+ }
+
+ int getIConst() const;
+ unsigned int getUConst() const;
+ float getFConst() const;
+ bool getBConst() const;
+ bool isZero() const;
+ TYuvCscStandardEXT getYuvCscStandardEXTConst() const;
+
+ bool operator==(const int i) const;
+ bool operator==(const unsigned int u) const;
+ bool operator==(const float f) const;
+ bool operator==(const bool b) const;
+ bool operator==(const TYuvCscStandardEXT s) const;
+ bool operator==(const TConstantUnion &constant) const;
+ bool operator!=(const int i) const;
+ bool operator!=(const unsigned int u) const;
+ bool operator!=(const float f) const;
+ bool operator!=(const bool b) const;
+ bool operator!=(const TYuvCscStandardEXT s) const;
+ bool operator!=(const TConstantUnion &constant) const;
+ bool operator>(const TConstantUnion &constant) const;
+ bool operator<(const TConstantUnion &constant) const;
+ static TConstantUnion add(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line);
+ static TConstantUnion sub(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line);
+ static TConstantUnion mul(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line);
+ TConstantUnion operator%(const TConstantUnion &constant) const;
+ static TConstantUnion rshift(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line);
+ static TConstantUnion lshift(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line);
+ TConstantUnion operator&(const TConstantUnion &constant) const;
+ TConstantUnion operator|(const TConstantUnion &constant) const;
+ TConstantUnion operator^(const TConstantUnion &constant) const;
+ TConstantUnion operator&&(const TConstantUnion &constant) const;
+ TConstantUnion operator||(const TConstantUnion &constant) const;
+
+ TBasicType getType() const { return type; }
+
+ private:
+ union
+ {
+ int iConst; // used for ivec, scalar ints
+ unsigned int uConst; // used for uvec, scalar uints
+ bool bConst; // used for bvec, scalar bools
+ float fConst; // used for vec, mat, scalar floats
+ TYuvCscStandardEXT yuvCscStandardEXTConst;
+ };
+
+ TBasicType type;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_CONSTANTUNION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Declarator.cpp b/gfx/angle/checkout/src/compiler/translator/Declarator.cpp
new file mode 100644
index 0000000000..7680c054d3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Declarator.cpp
@@ -0,0 +1,33 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Declarator.cpp:
+// Declarator type for parsing structure field declarators.
+
+#include "compiler/translator/Declarator.h"
+
+namespace sh
+{
+
+TDeclarator::TDeclarator(const ImmutableString &name, const TSourceLoc &line)
+ : mName(name), mArraySizes(nullptr), mLine(line)
+{
+ ASSERT(mName != "");
+}
+
+TDeclarator::TDeclarator(const ImmutableString &name,
+ const TVector<unsigned int> *arraySizes,
+ const TSourceLoc &line)
+ : mName(name), mArraySizes(arraySizes), mLine(line)
+{
+ ASSERT(mArraySizes);
+}
+
+bool TDeclarator::isArray() const
+{
+ return mArraySizes != nullptr && mArraySizes->size() > 0;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Declarator.h b/gfx/angle/checkout/src/compiler/translator/Declarator.h
new file mode 100644
index 0000000000..5268334946
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Declarator.h
@@ -0,0 +1,49 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Declarator.h:
+// Declarator type for parsing structure field declarators.
+
+#ifndef COMPILER_TRANSLATOR_DECLARATOR_H_
+#define COMPILER_TRANSLATOR_DECLARATOR_H_
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/ImmutableString.h"
+
+namespace sh
+{
+
+// Declarator like "a[2][4]". Only used for parsing structure field declarators.
+class TDeclarator : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TDeclarator(const ImmutableString &name, const TSourceLoc &line);
+
+ TDeclarator(const ImmutableString &name,
+ const TVector<unsigned int> *arraySizes,
+ const TSourceLoc &line);
+
+ const ImmutableString &name() const { return mName; }
+
+ bool isArray() const;
+ const TVector<unsigned int> *arraySizes() const { return mArraySizes; }
+
+ const TSourceLoc &line() const { return mLine; }
+
+ private:
+ const ImmutableString mName;
+
+ // Outermost array size is stored at the end of the vector.
+ const TVector<unsigned int> *const mArraySizes;
+
+ const TSourceLoc mLine;
+};
+
+using TDeclaratorList = TVector<TDeclarator *>;
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_DECLARATOR_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Diagnostics.cpp b/gfx/angle/checkout/src/compiler/translator/Diagnostics.cpp
new file mode 100644
index 0000000000..03066a319d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Diagnostics.cpp
@@ -0,0 +1,106 @@
+//
+// Copyright 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/Diagnostics.h"
+
+#include "common/debug.h"
+#include "compiler/preprocessor/SourceLocation.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/InfoSink.h"
+
+namespace sh
+{
+
+TDiagnostics::TDiagnostics(TInfoSinkBase &infoSink)
+ : mInfoSink(infoSink), mNumErrors(0), mNumWarnings(0)
+{}
+
+TDiagnostics::~TDiagnostics() {}
+
+void TDiagnostics::writeInfo(Severity severity,
+ const angle::pp::SourceLocation &loc,
+ const char *reason,
+ const char *token)
+{
+ switch (severity)
+ {
+ case SH_ERROR:
+ ++mNumErrors;
+ break;
+ case SH_WARNING:
+ ++mNumWarnings;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
+ mInfoSink.prefix(severity);
+ mInfoSink.location(loc.file, loc.line);
+ mInfoSink << "'" << token << "' : " << reason << "\n";
+}
+
+void TDiagnostics::globalError(const char *message)
+{
+ ++mNumErrors;
+ mInfoSink.prefix(SH_ERROR);
+ mInfoSink << message << "\n";
+}
+
+void TDiagnostics::error(const angle::pp::SourceLocation &loc,
+ const char *reason,
+ const char *token)
+{
+ writeInfo(SH_ERROR, loc, reason, token);
+}
+
+void TDiagnostics::warning(const angle::pp::SourceLocation &loc,
+ const char *reason,
+ const char *token)
+{
+ writeInfo(SH_WARNING, loc, reason, token);
+}
+
+void TDiagnostics::error(const TSourceLoc &loc, const char *reason, const char *token)
+{
+ angle::pp::SourceLocation srcLoc;
+ srcLoc.file = loc.first_file;
+ srcLoc.line = loc.first_line;
+ error(srcLoc, reason, token);
+}
+
+void TDiagnostics::warning(const TSourceLoc &loc, const char *reason, const char *token)
+{
+ angle::pp::SourceLocation srcLoc;
+ srcLoc.file = loc.first_file;
+ srcLoc.line = loc.first_line;
+ warning(srcLoc, reason, token);
+}
+
+void TDiagnostics::print(ID id, const angle::pp::SourceLocation &loc, const std::string &text)
+{
+ writeInfo(isError(id) ? SH_ERROR : SH_WARNING, loc, message(id), text.c_str());
+}
+
+void TDiagnostics::resetErrorCount()
+{
+ mNumErrors = 0;
+ mNumWarnings = 0;
+}
+
+PerformanceDiagnostics::PerformanceDiagnostics(TDiagnostics *diagnostics)
+ : mDiagnostics(diagnostics)
+{
+ ASSERT(diagnostics);
+}
+
+void PerformanceDiagnostics::warning(const TSourceLoc &loc, const char *reason, const char *token)
+{
+ mDiagnostics->warning(loc, reason, token);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Diagnostics.h b/gfx/angle/checkout/src/compiler/translator/Diagnostics.h
new file mode 100644
index 0000000000..8ed71b3d2b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Diagnostics.h
@@ -0,0 +1,67 @@
+//
+// Copyright 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_DIAGNOSTICS_H_
+#define COMPILER_TRANSLATOR_DIAGNOSTICS_H_
+
+#include "common/angleutils.h"
+#include "compiler/preprocessor/DiagnosticsBase.h"
+#include "compiler/translator/Severity.h"
+
+namespace sh
+{
+
+class TInfoSinkBase;
+struct TSourceLoc;
+
+class TDiagnostics : public angle::pp::Diagnostics, angle::NonCopyable
+{
+ public:
+ TDiagnostics(TInfoSinkBase &infoSink);
+ ~TDiagnostics() override;
+
+ int numErrors() const { return mNumErrors; }
+ int numWarnings() const { return mNumWarnings; }
+
+ void error(const angle::pp::SourceLocation &loc, const char *reason, const char *token);
+ void warning(const angle::pp::SourceLocation &loc, const char *reason, const char *token);
+
+ void error(const TSourceLoc &loc, const char *reason, const char *token);
+ void warning(const TSourceLoc &loc, const char *reason, const char *token);
+
+ void globalError(const char *message);
+
+ void resetErrorCount();
+
+ protected:
+ void writeInfo(Severity severity,
+ const angle::pp::SourceLocation &loc,
+ const char *reason,
+ const char *token);
+
+ void print(ID id, const angle::pp::SourceLocation &loc, const std::string &text) override;
+
+ private:
+ TInfoSinkBase &mInfoSink;
+ int mNumErrors;
+ int mNumWarnings;
+};
+
+// Diagnostics wrapper to use when the code is only allowed to generate warnings.
+class PerformanceDiagnostics : public angle::NonCopyable
+{
+ public:
+ PerformanceDiagnostics(TDiagnostics *diagnostics);
+
+ void warning(const TSourceLoc &loc, const char *reason, const char *token);
+
+ private:
+ TDiagnostics *mDiagnostics;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_DIAGNOSTICS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp b/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp
new file mode 100644
index 0000000000..80b238e055
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp
@@ -0,0 +1,304 @@
+//
+// Copyright 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/DirectiveHandler.h"
+
+#include <sstream>
+
+#include "angle_gl.h"
+#include "common/debug.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/Diagnostics.h"
+
+namespace sh
+{
+
+static TBehavior getBehavior(const std::string &str)
+{
+ const char kRequire[] = "require";
+ const char kEnable[] = "enable";
+ const char kDisable[] = "disable";
+ const char kWarn[] = "warn";
+
+ if (str == kRequire)
+ return EBhRequire;
+ else if (str == kEnable)
+ return EBhEnable;
+ else if (str == kDisable)
+ return EBhDisable;
+ else if (str == kWarn)
+ return EBhWarn;
+ return EBhUndefined;
+}
+
+TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
+ TDiagnostics &diagnostics,
+ int &shaderVersion,
+ sh::GLenum shaderType)
+ : mExtensionBehavior(extBehavior),
+ mDiagnostics(diagnostics),
+ mShaderVersion(shaderVersion),
+ mShaderType(shaderType)
+{}
+
+TDirectiveHandler::~TDirectiveHandler() {}
+
+void TDirectiveHandler::handleError(const angle::pp::SourceLocation &loc, const std::string &msg)
+{
+ mDiagnostics.error(loc, msg.c_str(), "");
+}
+
+void TDirectiveHandler::handlePragma(const angle::pp::SourceLocation &loc,
+ const std::string &name,
+ const std::string &value,
+ bool stdgl)
+{
+ if (stdgl)
+ {
+ const char kInvariant[] = "invariant";
+ const char kAll[] = "all";
+
+ if (name == kInvariant && value == kAll)
+ {
+ if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
+ {
+ // ESSL 3.00.4 section 4.6.1
+ mDiagnostics.error(
+ loc, "#pragma STDGL invariant(all) can not be used in fragment shader",
+ name.c_str());
+ }
+ mPragma.stdgl.invariantAll = true;
+ }
+ // The STDGL pragma is used to reserve pragmas for use by future
+ // revisions of GLSL. Do not generate an error on unexpected
+ // name and value.
+ return;
+ }
+ else
+ {
+ const char kOptimize[] = "optimize";
+ const char kDebug[] = "debug";
+ const char kOn[] = "on";
+ const char kOff[] = "off";
+
+ bool invalidValue = false;
+ if (name == kOptimize)
+ {
+ if (value == kOn)
+ mPragma.optimize = true;
+ else if (value == kOff)
+ mPragma.optimize = false;
+ else
+ invalidValue = true;
+ }
+ else if (name == kDebug)
+ {
+ if (value == kOn)
+ mPragma.debug = true;
+ else if (value == kOff)
+ mPragma.debug = false;
+ else
+ invalidValue = true;
+ }
+ else
+ {
+ mDiagnostics.report(angle::pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
+ return;
+ }
+
+ if (invalidValue)
+ {
+ mDiagnostics.error(loc, "invalid pragma value - 'on' or 'off' expected", value.c_str());
+ }
+ }
+}
+
+void TDirectiveHandler::handleExtension(const angle::pp::SourceLocation &loc,
+ const std::string &name,
+ const std::string &behavior)
+{
+ const char kExtAll[] = "all";
+
+ TBehavior behaviorVal = getBehavior(behavior);
+ if (behaviorVal == EBhUndefined)
+ {
+ mDiagnostics.error(loc, "behavior invalid", name.c_str());
+ return;
+ }
+
+ if (name == kExtAll)
+ {
+ if (behaviorVal == EBhRequire)
+ {
+ mDiagnostics.error(loc, "extension cannot have 'require' behavior", name.c_str());
+ }
+ else if (behaviorVal == EBhEnable)
+ {
+ mDiagnostics.error(loc, "extension cannot have 'enable' behavior", name.c_str());
+ }
+ else
+ {
+ for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
+ iter != mExtensionBehavior.end(); ++iter)
+ iter->second = behaviorVal;
+ }
+ return;
+ }
+
+ TExtensionBehavior::iterator iter = mExtensionBehavior.find(GetExtensionByName(name.c_str()));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ // OVR_multiview is implicitly enabled when OVR_multiview2 is enabled
+ if (name == "GL_OVR_multiview2")
+ {
+ constexpr char kMultiviewExtName[] = "GL_OVR_multiview";
+ iter = mExtensionBehavior.find(GetExtensionByName(kMultiviewExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+ }
+ // All the extensions listed in the spec here:
+ // https://www.khronos.org/registry/OpenGL/extensions/ANDROID/ANDROID_extension_pack_es31a.txt
+ // are implicitly enabled when GL_ANDROID_extension_pack_es31a is enabled
+ if (name == "GL_ANDROID_extension_pack_es31a")
+ {
+ constexpr char kGeometryShaderExtName[] = "GL_EXT_geometry_shader";
+ constexpr char kTessellationShaderExtName[] = "GL_EXT_tessellation_shader";
+ constexpr char kGpuShader5ExtName[] = "GL_EXT_gpu_shader5";
+ constexpr char kTextureBufferExtName[] = "GL_EXT_texture_buffer";
+ constexpr char kTextureCubeMapArrayExtName[] = "GL_EXT_texture_cube_map_array";
+ constexpr char kSampleVariablesExtName[] = "GL_OES_sample_variables";
+ constexpr char kShaderMultisampleInterpolationExtName[] =
+ "GL_OES_shader_multisample_interpolation";
+ constexpr char kShaderImageAtomicExtName[] = "GL_OES_shader_image_atomic";
+ constexpr char kTextureStorageMultisample2dArrayExtName[] =
+ "GL_OES_texture_storage_multisample_2d_array";
+ iter = mExtensionBehavior.find(GetExtensionByName(kGeometryShaderExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kTessellationShaderExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kGpuShader5ExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kTextureBufferExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kTextureCubeMapArrayExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kSampleVariablesExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter =
+ mExtensionBehavior.find(GetExtensionByName(kShaderMultisampleInterpolationExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kShaderImageAtomicExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(
+ GetExtensionByName(kTextureStorageMultisample2dArrayExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+ }
+ // EXT_shader_io_blocks is implicitly enabled when EXT_geometry_shader or
+ // EXT_tessellation_shader is enabled.
+ if (name == "GL_EXT_geometry_shader" || name == "GL_EXT_tessellation_shader")
+ {
+ constexpr char kIOBlocksExtName[] = "GL_EXT_shader_io_blocks";
+ iter = mExtensionBehavior.find(GetExtensionByName(kIOBlocksExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+ }
+ // GL_APPLE_clip_distance is implicitly enabled when GL_EXT_clip_cull_distance is enabled
+ else if (name == "GL_EXT_clip_cull_distance")
+ {
+ // This extension only can be enabled on greater than ESSL 300
+ if (mShaderVersion < 300)
+ {
+ mDiagnostics.error(loc, "extension can be enabled on greater than ESSL 300",
+ name.c_str());
+ return;
+ }
+
+ constexpr char kAPPLEClipDistanceEXTName[] = "GL_APPLE_clip_distance";
+ iter = mExtensionBehavior.find(GetExtensionByName(kAPPLEClipDistanceEXTName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+ }
+ return;
+ }
+
+ switch (behaviorVal)
+ {
+ case EBhRequire:
+ mDiagnostics.error(loc, "extension is not supported", name.c_str());
+ break;
+ case EBhEnable:
+ case EBhWarn:
+ case EBhDisable:
+ mDiagnostics.warning(loc, "extension is not supported", name.c_str());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void TDirectiveHandler::handleVersion(const angle::pp::SourceLocation &loc,
+ int version,
+ ShShaderSpec spec)
+{
+ if (((version == 100 || version == 300 || version == 310 || version == 320) &&
+ !IsDesktopGLSpec(spec)) ||
+ IsDesktopGLSpec(spec))
+ {
+ mShaderVersion = version;
+ }
+ else
+ {
+ std::stringstream stream = sh::InitializeStream<std::stringstream>();
+ stream << version;
+ std::string str = stream.str();
+ mDiagnostics.error(loc, "client/version number not supported", str.c_str());
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.h b/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.h
new file mode 100644
index 0000000000..6fb54558ef
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.h
@@ -0,0 +1,57 @@
+//
+// Copyright 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
+#define COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/angleutils.h"
+#include "compiler/preprocessor/DirectiveHandlerBase.h"
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/Pragma.h"
+
+namespace sh
+{
+class TDiagnostics;
+
+class TDirectiveHandler : public angle::pp::DirectiveHandler, angle::NonCopyable
+{
+ public:
+ TDirectiveHandler(TExtensionBehavior &extBehavior,
+ TDiagnostics &diagnostics,
+ int &shaderVersion,
+ sh::GLenum shaderType);
+ ~TDirectiveHandler() override;
+
+ const TPragma &pragma() const { return mPragma; }
+ const TExtensionBehavior &extensionBehavior() const { return mExtensionBehavior; }
+
+ void handleError(const angle::pp::SourceLocation &loc, const std::string &msg) override;
+
+ void handlePragma(const angle::pp::SourceLocation &loc,
+ const std::string &name,
+ const std::string &value,
+ bool stdgl) override;
+
+ void handleExtension(const angle::pp::SourceLocation &loc,
+ const std::string &name,
+ const std::string &behavior) override;
+
+ void handleVersion(const angle::pp::SourceLocation &loc,
+ int version,
+ ShShaderSpec spec) override;
+
+ private:
+ TPragma mPragma;
+ TExtensionBehavior &mExtensionBehavior;
+ TDiagnostics &mDiagnostics;
+ int &mShaderVersion;
+ sh::GLenum mShaderType;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/DriverUniformMetal.h b/gfx/angle/checkout/src/compiler/translator/DriverUniformMetal.h
new file mode 100644
index 0000000000..47e075b2e7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/DriverUniformMetal.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// DriverUniformMetal:
+// Struct defining the default driver uniforms for direct and SpirV based ANGLE translation
+//
+
+#ifndef LIBANGLE_RENDERER_METAL_DRIVERUNIFORMMETAL_H_
+#define LIBANGLE_RENDERER_METAL_DRIVERUNIFORMMETAL_H_
+
+#include "compiler/translator/tree_util/DriverUniform.h"
+
+namespace sh
+{
+
+class DriverUniformMetal : public DriverUniformExtended
+{
+ public:
+ DriverUniformMetal(DriverUniformMode mode) : DriverUniformExtended(mode) {}
+ DriverUniformMetal() : DriverUniformExtended(DriverUniformMode::InterfaceBlock) {}
+ ~DriverUniformMetal() override {}
+
+ TIntermTyped *getCoverageMaskField() const;
+
+ protected:
+ TFieldList *createUniformFields(TSymbolTable *symbolTable) override;
+};
+
+} // namespace sh
+
+#endif /* LIBANGLE_RENDERER_METAL_DRIVERUNIFORMMETAL_H_ */
diff --git a/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.cpp b/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.cpp
new file mode 100644
index 0000000000..9c16393272
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.cpp
@@ -0,0 +1,125 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ExtensionBehavior.cpp: Extension name enumeration and data structures for storing extension
+// behavior.
+
+#include "compiler/translator/ExtensionBehavior.h"
+
+#include "common/debug.h"
+
+#include <string.h>
+
+#define LIST_EXTENSIONS(OP) \
+ OP(ANDROID_extension_pack_es31a) \
+ OP(ANGLE_base_vertex_base_instance_shader_builtin) \
+ OP(ANGLE_multi_draw) \
+ OP(ANGLE_shader_pixel_local_storage) \
+ OP(ANGLE_texture_multisample) \
+ OP(APPLE_clip_distance) \
+ OP(ARB_texture_rectangle) \
+ OP(ARM_shader_framebuffer_fetch) \
+ OP(EXT_blend_func_extended) \
+ OP(EXT_clip_cull_distance) \
+ OP(EXT_draw_buffers) \
+ OP(EXT_frag_depth) \
+ OP(EXT_geometry_shader) \
+ OP(OES_geometry_shader) \
+ OP(OES_shader_io_blocks) \
+ OP(EXT_shader_io_blocks) \
+ OP(EXT_gpu_shader5) \
+ OP(EXT_primitive_bounding_box) \
+ OP(OES_primitive_bounding_box) \
+ OP(EXT_shader_framebuffer_fetch) \
+ OP(EXT_shader_framebuffer_fetch_non_coherent) \
+ OP(EXT_shader_non_constant_global_initializers) \
+ OP(EXT_shader_texture_lod) \
+ OP(EXT_shadow_samplers) \
+ OP(EXT_tessellation_shader) \
+ OP(EXT_texture_buffer) \
+ OP(EXT_texture_cube_map_array) \
+ OP(EXT_YUV_target) \
+ OP(KHR_blend_equation_advanced) \
+ OP(NV_EGL_stream_consumer_external) \
+ OP(NV_shader_framebuffer_fetch) \
+ OP(NV_shader_noperspective_interpolation) \
+ OP(OES_EGL_image_external) \
+ OP(OES_EGL_image_external_essl3) \
+ OP(OES_sample_variables) \
+ OP(OES_shader_multisample_interpolation) \
+ OP(OES_shader_image_atomic) \
+ OP(OES_standard_derivatives) \
+ OP(OES_texture_3D) \
+ OP(OES_texture_buffer) \
+ OP(OES_texture_cube_map_array) \
+ OP(OES_texture_storage_multisample_2d_array) \
+ OP(OVR_multiview) \
+ OP(OVR_multiview2) \
+ OP(WEBGL_video_texture)
+
+namespace sh
+{
+
+#define RETURN_EXTENSION_NAME_CASE(ext) \
+ case TExtension::ext: \
+ return "GL_" #ext;
+
+const char *GetExtensionNameString(TExtension extension)
+{
+ switch (extension)
+ {
+ LIST_EXTENSIONS(RETURN_EXTENSION_NAME_CASE)
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+#define RETURN_EXTENSION_IF_NAME_MATCHES(ext) \
+ if (strcmp(extWithoutGLPrefix, #ext) == 0) \
+ { \
+ return TExtension::ext; \
+ }
+
+TExtension GetExtensionByName(const char *extension)
+{
+ // If first characters of the extension don't equal "GL_", early out.
+ if (strncmp(extension, "GL_", 3) != 0)
+ {
+ return TExtension::UNDEFINED;
+ }
+ const char *extWithoutGLPrefix = extension + 3;
+
+ LIST_EXTENSIONS(RETURN_EXTENSION_IF_NAME_MATCHES)
+
+ return TExtension::UNDEFINED;
+}
+
+const char *GetBehaviorString(TBehavior b)
+{
+ switch (b)
+ {
+ case EBhRequire:
+ return "require";
+ case EBhEnable:
+ return "enable";
+ case EBhWarn:
+ return "warn";
+ case EBhDisable:
+ return "disable";
+ default:
+ return nullptr;
+ }
+}
+
+bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, TExtension extension)
+{
+ ASSERT(extension != TExtension::UNDEFINED);
+ auto iter = extBehavior.find(extension);
+ return iter != extBehavior.end() &&
+ (iter->second == EBhEnable || iter->second == EBhRequire || iter->second == EBhWarn);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.h b/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.h
new file mode 100644
index 0000000000..64b0748854
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.h
@@ -0,0 +1,93 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ExtensionBehavior.h: Extension name enumeration and data structures for storing extension
+// behavior.
+
+#ifndef COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
+#define COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
+
+#include <cstdint>
+#include <map>
+
+namespace sh
+{
+
+enum class TExtension : uint8_t
+{
+ UNDEFINED, // Special value used to indicate no extension.
+
+ ANDROID_extension_pack_es31a,
+ ANGLE_base_vertex_base_instance_shader_builtin,
+ ANGLE_multi_draw,
+ ANGLE_shader_pixel_local_storage,
+ ANGLE_texture_multisample,
+ APPLE_clip_distance,
+ ARB_fragment_shader_interlock,
+ ARB_texture_rectangle,
+ ARM_shader_framebuffer_fetch,
+ EXT_YUV_target,
+ EXT_blend_func_extended,
+ EXT_clip_cull_distance,
+ EXT_draw_buffers,
+ EXT_frag_depth,
+ EXT_geometry_shader,
+ EXT_gpu_shader5,
+ EXT_primitive_bounding_box,
+ EXT_shader_framebuffer_fetch,
+ EXT_shader_framebuffer_fetch_non_coherent,
+ EXT_shader_io_blocks,
+ EXT_shader_non_constant_global_initializers,
+ EXT_shader_texture_lod,
+ EXT_shadow_samplers,
+ EXT_tessellation_shader,
+ EXT_texture_buffer,
+ EXT_texture_cube_map_array,
+ INTEL_fragment_shader_ordering,
+ KHR_blend_equation_advanced,
+ NV_EGL_stream_consumer_external,
+ NV_fragment_shader_interlock,
+ NV_shader_framebuffer_fetch,
+ NV_shader_noperspective_interpolation,
+ OES_EGL_image_external,
+ OES_EGL_image_external_essl3,
+ OES_geometry_shader,
+ OES_primitive_bounding_box,
+ OES_sample_variables,
+ OES_shader_image_atomic,
+ OES_shader_io_blocks,
+ OES_shader_multisample_interpolation,
+ OES_standard_derivatives,
+ OES_texture_3D,
+ OES_texture_buffer,
+ OES_texture_cube_map_array,
+ OES_texture_storage_multisample_2d_array,
+ OVR_multiview,
+ OVR_multiview2,
+ WEBGL_video_texture,
+};
+
+enum TBehavior : uint8_t
+{
+ EBhRequire,
+ EBhEnable,
+ EBhWarn,
+ EBhDisable,
+ EBhUndefined
+};
+
+const char *GetExtensionNameString(TExtension extension);
+TExtension GetExtensionByName(const char *extension);
+
+const char *GetBehaviorString(TBehavior b);
+
+// Mapping between extension id and behavior.
+typedef std::map<TExtension, TBehavior> TExtensionBehavior;
+
+bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, TExtension extension);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.cpp
new file mode 100644
index 0000000000..563dbab185
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.cpp
@@ -0,0 +1,118 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ExtensionGLSL.cpp: Implements the TExtensionGLSL class that tracks GLSL extension requirements
+// of shaders.
+
+#include "compiler/translator/ExtensionGLSL.h"
+
+#include "compiler/translator/VersionGLSL.h"
+
+namespace sh
+{
+
+TExtensionGLSL::TExtensionGLSL(ShShaderOutput output)
+ : TIntermTraverser(true, false, false), mTargetVersion(ShaderOutputTypeToGLSLVersion(output))
+{}
+
+const std::set<std::string> &TExtensionGLSL::getEnabledExtensions() const
+{
+ return mEnabledExtensions;
+}
+
+const std::set<std::string> &TExtensionGLSL::getRequiredExtensions() const
+{
+ return mRequiredExtensions;
+}
+
+bool TExtensionGLSL::visitUnary(Visit, TIntermUnary *node)
+{
+ checkOperator(node);
+
+ return true;
+}
+
+bool TExtensionGLSL::visitAggregate(Visit, TIntermAggregate *node)
+{
+ checkOperator(node);
+
+ return true;
+}
+
+void TExtensionGLSL::checkOperator(TIntermOperator *node)
+{
+ if (mTargetVersion < GLSL_VERSION_130)
+ {
+ return;
+ }
+
+ switch (node->getOp())
+ {
+ case EOpAbs:
+ break;
+
+ case EOpSign:
+ break;
+
+ case EOpMix:
+ break;
+
+ case EOpFloatBitsToInt:
+ case EOpFloatBitsToUint:
+ case EOpIntBitsToFloat:
+ case EOpUintBitsToFloat:
+ if (mTargetVersion < GLSL_VERSION_330)
+ {
+ // Bit conversion functions cannot be emulated.
+ mRequiredExtensions.insert("GL_ARB_shader_bit_encoding");
+ }
+ break;
+
+ case EOpPackSnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackHalf2x16:
+ if (mTargetVersion < GLSL_VERSION_420)
+ {
+ mEnabledExtensions.insert("GL_ARB_shading_language_packing");
+
+ if (mTargetVersion < GLSL_VERSION_330)
+ {
+ // floatBitsToUint and uintBitsToFloat are needed to emulate
+ // packHalf2x16 and unpackHalf2x16 respectively and cannot be
+ // emulated themselves.
+ mRequiredExtensions.insert("GL_ARB_shader_bit_encoding");
+ }
+ }
+ break;
+
+ case EOpPackUnorm2x16:
+ case EOpUnpackUnorm2x16:
+ if (mTargetVersion < GLSL_VERSION_410)
+ {
+ mEnabledExtensions.insert("GL_ARB_shading_language_packing");
+ }
+ break;
+
+ case EOpBeginInvocationInterlockNV:
+ case EOpEndInvocationInterlockNV:
+ mRequiredExtensions.insert("GL_NV_fragment_shader_interlock");
+ break;
+
+ case EOpBeginFragmentShaderOrderingINTEL:
+ mRequiredExtensions.insert("GL_INTEL_fragment_shader_ordering");
+ break;
+
+ case EOpBeginInvocationInterlockARB:
+ case EOpEndInvocationInterlockARB:
+ mRequiredExtensions.insert("GL_ARB_fragment_shader_interlock");
+ break;
+
+ default:
+ break;
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h b/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h
new file mode 100644
index 0000000000..b07e4e95a9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h
@@ -0,0 +1,44 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ExtensionGLSL.h: Defines the TExtensionGLSL class that tracks GLSL extension requirements of
+// shaders.
+
+#ifndef COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
+#define COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
+
+#include <set>
+#include <string>
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+// Traverses the intermediate tree to determine which GLSL extensions are required
+// to support the shader.
+class TExtensionGLSL : public TIntermTraverser
+{
+ public:
+ TExtensionGLSL(ShShaderOutput output);
+
+ const std::set<std::string> &getEnabledExtensions() const;
+ const std::set<std::string> &getRequiredExtensions() const;
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+ private:
+ void checkOperator(TIntermOperator *node);
+
+ int mTargetVersion;
+
+ std::set<std::string> mEnabledExtensions;
+ std::set<std::string> mRequiredExtensions;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp b/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp
new file mode 100644
index 0000000000..729e452893
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp
@@ -0,0 +1,76 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FlagStd140Structs.cpp: Find structs in std140 blocks, where the padding added in the translator
+// conflicts with the "natural" unpadded type.
+
+#include "compiler/translator/FlagStd140Structs.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class FlagStd140StructsTraverser : public TIntermTraverser
+{
+ public:
+ FlagStd140StructsTraverser() : TIntermTraverser(true, false, false) {}
+
+ const std::vector<MappedStruct> getMappedStructs() const { return mMappedStructs; }
+
+ protected:
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+
+ private:
+ void mapBlockStructMembers(TIntermSymbol *blockDeclarator, const TInterfaceBlock *block);
+
+ std::vector<MappedStruct> mMappedStructs;
+};
+
+void FlagStd140StructsTraverser::mapBlockStructMembers(TIntermSymbol *blockDeclarator,
+ const TInterfaceBlock *block)
+{
+ for (auto *field : block->fields())
+ {
+ if (field->type()->getBasicType() == EbtStruct)
+ {
+ MappedStruct mappedStruct;
+ mappedStruct.blockDeclarator = blockDeclarator;
+ mappedStruct.field = field;
+ mMappedStructs.push_back(mappedStruct);
+ }
+ }
+}
+
+bool FlagStd140StructsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ TIntermTyped *declarator = node->getSequence()->back()->getAsTyped();
+ if (declarator->getBasicType() == EbtInterfaceBlock)
+ {
+ const TInterfaceBlock *block = declarator->getType().getInterfaceBlock();
+ if (block->blockStorage() == EbsStd140)
+ {
+ mapBlockStructMembers(declarator->getAsSymbolNode(), block);
+ }
+ }
+ return false;
+}
+
+} // anonymous namespace
+
+std::vector<MappedStruct> FlagStd140Structs(TIntermNode *node)
+{
+ FlagStd140StructsTraverser flaggingTraversal;
+
+ node->traverse(&flaggingTraversal);
+
+ return flaggingTraversal.getMappedStructs();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.h b/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.h
new file mode 100644
index 0000000000..2ff10b2319
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FlagStd140Structs.h: Find structs in std140 blocks, where the padding added in the translator
+// conflicts with the "natural" unpadded type.
+
+#ifndef COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
+#define COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
+
+#include <vector>
+
+namespace sh
+{
+
+class TField;
+class TIntermNode;
+class TIntermSymbol;
+
+struct MappedStruct
+{
+ TIntermSymbol *blockDeclarator;
+ TField *field;
+};
+
+std::vector<MappedStruct> FlagStd140Structs(TIntermNode *node);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp b/gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp
new file mode 100644
index 0000000000..8b574e9363
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp
@@ -0,0 +1,179 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FunctionLookup.cpp: Used for storing function calls that have not yet been resolved during
+// parsing.
+//
+
+#include "compiler/translator/FunctionLookup.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+
+namespace sh
+{
+
+namespace
+{
+
+const char kFunctionMangledNameSeparator = '(';
+
+constexpr const ImmutableString kEmptyName("");
+
+// Helper function for GetMangledNames
+// Gets all ordered combinations of elements in list[currentIndex, end]
+std::vector<std::vector<int>> GetImplicitConversionCombinations(const std::vector<int> &list)
+{
+ std::vector<std::vector<int>> target;
+ target.push_back(std::vector<int>());
+
+ for (size_t currentIndex = 0; currentIndex < list.size(); currentIndex++)
+ {
+ size_t prevIterSize = target.size();
+ for (size_t copyIndex = 0; copyIndex < prevIterSize; copyIndex++)
+ {
+ std::vector<int> combination = target[copyIndex];
+ combination.push_back(list[currentIndex]);
+ target.push_back(combination);
+ }
+ }
+
+ return target;
+}
+
+} // anonymous namespace
+
+TFunctionLookup::TFunctionLookup(const ImmutableString &name,
+ const TType *constructorType,
+ const TSymbol *symbol)
+ : mName(name), mConstructorType(constructorType), mThisNode(nullptr), mSymbol(symbol)
+{}
+
+// static
+TFunctionLookup *TFunctionLookup::CreateConstructor(const TType *type)
+{
+ ASSERT(type != nullptr);
+ return new TFunctionLookup(kEmptyName, type, nullptr);
+}
+
+// static
+TFunctionLookup *TFunctionLookup::CreateFunctionCall(const ImmutableString &name,
+ const TSymbol *symbol)
+{
+ ASSERT(name != "");
+ return new TFunctionLookup(name, nullptr, symbol);
+}
+
+const ImmutableString &TFunctionLookup::name() const
+{
+ return mName;
+}
+
+ImmutableString TFunctionLookup::getMangledName() const
+{
+ return GetMangledName(mName.data(), mArguments);
+}
+
+ImmutableString TFunctionLookup::GetMangledName(const char *functionName,
+ const TIntermSequence &arguments)
+{
+ std::string newName(functionName);
+ newName += kFunctionMangledNameSeparator;
+
+ for (TIntermNode *argument : arguments)
+ {
+ newName += argument->getAsTyped()->getType().getMangledName();
+ }
+ return ImmutableString(newName);
+}
+
+std::vector<ImmutableString> GetMangledNames(const char *functionName,
+ const TIntermSequence &arguments)
+{
+ std::vector<ImmutableString> target;
+
+ std::vector<int> indexes;
+ for (int i = 0; i < static_cast<int>(arguments.size()); i++)
+ {
+ TIntermNode *argument = arguments[i];
+ TBasicType argType = argument->getAsTyped()->getType().getBasicType();
+ if (argType == EbtInt || argType == EbtUInt)
+ {
+ indexes.push_back(i);
+ }
+ }
+
+ std::vector<std::vector<int>> combinations = GetImplicitConversionCombinations(indexes);
+ for (const std::vector<int> &combination : combinations)
+ {
+ // combination: ordered list of indexes for arguments that should be converted to float
+ std::string newName(functionName);
+ newName += kFunctionMangledNameSeparator;
+ // combination[currentIndex] represents index of next argument to be converted
+ int currentIndex = 0;
+ for (int i = 0; i < (int)arguments.size(); i++)
+ {
+ TIntermNode *argument = arguments[i];
+
+ if (currentIndex != static_cast<int>(combination.size()) &&
+ combination[currentIndex] == i)
+ {
+ // Convert
+ TType type = argument->getAsTyped()->getType();
+ type.setBasicType(EbtFloat);
+ newName += type.getMangledName();
+ currentIndex++;
+ }
+ else
+ {
+ // Don't convert
+ newName += argument->getAsTyped()->getType().getMangledName();
+ }
+ }
+ target.push_back(ImmutableString(newName));
+ }
+
+ return target;
+}
+
+std::vector<ImmutableString> TFunctionLookup::getMangledNamesForImplicitConversions() const
+{
+ return GetMangledNames(mName.data(), mArguments);
+}
+
+bool TFunctionLookup::isConstructor() const
+{
+ return mConstructorType != nullptr;
+}
+
+const TType &TFunctionLookup::constructorType() const
+{
+ return *mConstructorType;
+}
+
+void TFunctionLookup::setThisNode(TIntermTyped *thisNode)
+{
+ mThisNode = thisNode;
+}
+
+TIntermTyped *TFunctionLookup::thisNode() const
+{
+ return mThisNode;
+}
+
+void TFunctionLookup::addArgument(TIntermTyped *argument)
+{
+ mArguments.push_back(argument);
+}
+
+TIntermSequence &TFunctionLookup::arguments()
+{
+ return mArguments;
+}
+
+const TSymbol *TFunctionLookup::symbol() const
+{
+ return mSymbol;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/FunctionLookup.h b/gfx/angle/checkout/src/compiler/translator/FunctionLookup.h
new file mode 100644
index 0000000000..6565c205eb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/FunctionLookup.h
@@ -0,0 +1,60 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FunctionLookup.h: Used for storing function calls that have not yet been resolved during parsing.
+//
+
+#ifndef COMPILER_TRANSLATOR_FUNCTIONLOOKUP_H_
+#define COMPILER_TRANSLATOR_FUNCTIONLOOKUP_H_
+
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+// A function look-up.
+class TFunctionLookup : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+
+ static TFunctionLookup *CreateConstructor(const TType *type);
+ static TFunctionLookup *CreateFunctionCall(const ImmutableString &name, const TSymbol *symbol);
+
+ const ImmutableString &name() const;
+ ImmutableString getMangledName() const;
+ static ImmutableString GetMangledName(const char *functionName,
+ const TIntermSequence &arguments);
+ std::vector<ImmutableString> getMangledNamesForImplicitConversions() const;
+
+ bool isConstructor() const;
+ const TType &constructorType() const;
+
+ void setThisNode(TIntermTyped *thisNode);
+ TIntermTyped *thisNode() const;
+
+ void addArgument(TIntermTyped *argument);
+ TIntermSequence &arguments();
+
+ // Symbol looked up in the lexical phase using only the name of the function.
+ // This does not necessarily correspond to the correct overloaded function.
+ const TSymbol *symbol() const;
+
+ private:
+ TFunctionLookup(const ImmutableString &name,
+ const TType *constructorType,
+ const TSymbol *symbol);
+
+ const ImmutableString mName;
+ const TType *const mConstructorType;
+ TIntermTyped *mThisNode;
+ TIntermSequence mArguments;
+ const TSymbol *mSymbol;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_FUNCTIONLOOKUP_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/HashNames.cpp b/gfx/angle/checkout/src/compiler/translator/HashNames.cpp
new file mode 100644
index 0000000000..fc188ff582
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/HashNames.cpp
@@ -0,0 +1,99 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/HashNames.h"
+
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr const ImmutableString kHashedNamePrefix("webgl_");
+
+ImmutableString HashName(const ImmutableString &name, ShHashFunction64 hashFunction)
+{
+ ASSERT(!name.empty());
+ ASSERT(hashFunction);
+ khronos_uint64_t number = (*hashFunction)(name.data(), name.length());
+
+ // Build the hashed name in place.
+ static const unsigned int kHexStrMaxLength = sizeof(number) * 2;
+ static const size_t kHashedNameMaxLength = kHashedNamePrefix.length() + kHexStrMaxLength;
+
+ ImmutableStringBuilder hashedName(kHashedNameMaxLength);
+ hashedName << kHashedNamePrefix;
+
+ hashedName.appendHex(number);
+
+ return hashedName;
+}
+
+void AddToNameMapIfNotMapped(const ImmutableString &name,
+ const ImmutableString &hashedName,
+ NameMap *nameMap)
+{
+ if (nameMap)
+ {
+ NameMap::const_iterator it = nameMap->find(name.data());
+ if (it != nameMap->end())
+ {
+ // (How bout returning?)
+ return;
+ }
+ (*nameMap)[name.data()] = hashedName.data();
+ }
+}
+
+} // anonymous namespace
+
+ImmutableString HashName(const ImmutableString &name,
+ ShHashFunction64 hashFunction,
+ NameMap *nameMap)
+{
+ const ImmutableString kUnhashedNamePrefix(kUserDefinedNamePrefix);
+
+ if (hashFunction == nullptr)
+ {
+ if (name.length() + kUnhashedNamePrefix.length() > kESSLMaxIdentifierLength)
+ {
+ // If the identifier length is already close to the limit, we can't prefix it. This is
+ // not a problem since there are no builtins or ANGLE's internal variables that would
+ // have as long names and could conflict.
+ return name;
+ }
+ ImmutableStringBuilder prefixedName(kUnhashedNamePrefix.length() + name.length());
+ prefixedName << kUnhashedNamePrefix << name;
+ ImmutableString res = prefixedName;
+ AddToNameMapIfNotMapped(name, res, nameMap);
+ return res;
+ }
+
+ // Has a hash function
+ ImmutableString hashedName = HashName(name, hashFunction);
+ AddToNameMapIfNotMapped(name, hashedName, nameMap);
+ return hashedName;
+}
+
+ImmutableString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap)
+{
+ if (symbol->symbolType() == SymbolType::Empty)
+ {
+ return kEmptyImmutableString;
+ }
+ if (symbol->symbolType() == SymbolType::AngleInternal ||
+ symbol->symbolType() == SymbolType::BuiltIn)
+ {
+ return symbol->name();
+ }
+ return HashName(symbol->name(), hashFunction, nameMap);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/HashNames.h b/gfx/angle/checkout/src/compiler/translator/HashNames.h
new file mode 100644
index 0000000000..3742095129
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/HashNames.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_HASHNAMES_H_
+#define COMPILER_TRANSLATOR_HASHNAMES_H_
+
+#include <map>
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+typedef std::map<TPersistString, TPersistString> NameMap;
+
+class ImmutableString;
+class TSymbol;
+
+ImmutableString HashName(const ImmutableString &name,
+ ShHashFunction64 hashFunction,
+ NameMap *nameMap);
+
+// Hash user-defined name for GLSL output, with special handling for internal names.
+// The nameMap parameter is optional and is used to cache hashed names if set.
+ImmutableString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_HASHNAMES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.cpp
new file mode 100644
index 0000000000..51d1a1abdd
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.cpp
@@ -0,0 +1,401 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ImageFunctionHLSL: Class for writing implementations of ESSL image functions into HLSL output.
+//
+
+#include "compiler/translator/ImageFunctionHLSL.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/UtilsHLSL.h"
+
+namespace sh
+{
+
+// static
+ImmutableString ImageFunctionHLSL::GetImageReference(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction)
+{
+ static const ImmutableString kImageIndexStr("[index]");
+ if (imageFunction.readonly)
+ {
+ static const ImmutableString kReadonlyImagesStr("readonlyImages");
+ ImmutableString suffix(
+ TextureGroupSuffix(imageFunction.image, imageFunction.imageInternalFormat));
+ out << " const uint index = imageIndex - readonlyImageIndexOffset" << suffix.data()
+ << ";\n";
+ ImmutableStringBuilder imageRefBuilder(kReadonlyImagesStr.length() + suffix.length() +
+ kImageIndexStr.length());
+ imageRefBuilder << kReadonlyImagesStr << suffix << kImageIndexStr;
+ return imageRefBuilder;
+ }
+ else
+ {
+ static const ImmutableString kImagesStr("images");
+ ImmutableString suffix(
+ RWTextureGroupSuffix(imageFunction.image, imageFunction.imageInternalFormat));
+ out << " const uint index = imageIndex - imageIndexOffset" << suffix.data() << ";\n";
+ ImmutableStringBuilder imageRefBuilder(kImagesStr.length() + suffix.length() +
+ kImageIndexStr.length());
+ imageRefBuilder << kImagesStr << suffix << kImageIndexStr;
+ return imageRefBuilder;
+ }
+}
+
+void ImageFunctionHLSL::OutputImageFunctionArgumentList(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction)
+{
+ out << "uint imageIndex";
+
+ if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::LOAD ||
+ imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE)
+ {
+ switch (imageFunction.image)
+ {
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ out << ", int2 p";
+ break;
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ out << ", int3 p";
+ break;
+ case EbtUImageBuffer:
+ case EbtIImageBuffer:
+ case EbtImageBuffer:
+ out << ", int p";
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE)
+ {
+ switch (imageFunction.image)
+ {
+ case EbtImage2D:
+ case EbtImage3D:
+ case EbtImageCube:
+ case EbtImage2DArray:
+ case EbtImageBuffer:
+ out << ", float4 data";
+ break;
+ case EbtIImage2D:
+ case EbtIImage3D:
+ case EbtIImageCube:
+ case EbtIImage2DArray:
+ case EbtIImageBuffer:
+ out << ", int4 data";
+ break;
+ case EbtUImage2D:
+ case EbtUImage3D:
+ case EbtUImageCube:
+ case EbtUImage2DArray:
+ case EbtUImageBuffer:
+ out << ", uint4 data";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+}
+
+// static
+void ImageFunctionHLSL::OutputImageSizeFunctionBody(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference)
+{
+ if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
+ IsImageCube(imageFunction.image))
+ {
+ // "depth" stores either the number of layers in an array texture or 3D depth
+ out << " uint width; uint height; uint depth;\n"
+ << " " << imageReference << ".GetDimensions(width, height, depth);\n";
+ }
+ else if (IsImage2D(imageFunction.image))
+ {
+ out << " uint width; uint height;\n"
+ << " " << imageReference << ".GetDimensions(width, height);\n";
+ }
+ else if (IsImageBuffer(imageFunction.image))
+ {
+ out << " uint width;\n"
+ << " " << imageReference << ".GetDimensions(width);\n";
+ }
+ else
+ UNREACHABLE();
+
+ if (strcmp(imageFunction.getReturnType(), "int3") == 0)
+ {
+ out << " return int3(width, height, depth);\n";
+ }
+ else if (strcmp(imageFunction.getReturnType(), "int2") == 0)
+ {
+ out << " return int2(width, height);\n";
+ }
+ else if (strcmp(imageFunction.getReturnType(), "int") == 0)
+ out << " return int(width);\n";
+ else
+ UNREACHABLE();
+}
+
+// static
+void ImageFunctionHLSL::OutputImageLoadFunctionBody(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference)
+{
+ if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
+ IsImageCube(imageFunction.image))
+ {
+ out << " return " << imageReference << "[uint3(p.x, p.y, p.z)];\n";
+ }
+ else if (IsImage2D(imageFunction.image))
+ {
+ out << " return " << imageReference << "[uint2(p.x, p.y)];\n";
+ }
+ else if (IsImageBuffer(imageFunction.image))
+ {
+ out << " return " << imageReference << "[uint(p.x)];\n";
+ }
+ else
+ UNREACHABLE();
+}
+
+// static
+void ImageFunctionHLSL::OutputImageStoreFunctionBody(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference)
+{
+ if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
+ IsImage2D(imageFunction.image) || IsImageCube(imageFunction.image) ||
+ IsImageBuffer(imageFunction.image))
+ {
+ out << " " << imageReference << "[p] = data;\n";
+ }
+ else
+ UNREACHABLE();
+}
+
+ImmutableString ImageFunctionHLSL::ImageFunction::name() const
+{
+ static const ImmutableString kGlImageName("gl_image");
+
+ ImmutableString suffix(nullptr);
+ if (readonly)
+ {
+ suffix = ImmutableString(TextureTypeSuffix(image, imageInternalFormat));
+ }
+ else
+ {
+ suffix = ImmutableString(RWTextureTypeSuffix(image, imageInternalFormat));
+ }
+
+ ImmutableStringBuilder name(kGlImageName.length() + suffix.length() + 5u);
+
+ name << kGlImageName << suffix;
+
+ switch (method)
+ {
+ case Method::SIZE:
+ name << "Size";
+ break;
+ case Method::LOAD:
+ name << "Load";
+ break;
+ case Method::STORE:
+ name << "Store";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return name;
+}
+
+ImageFunctionHLSL::ImageFunction::DataType ImageFunctionHLSL::ImageFunction::getDataType(
+ TLayoutImageInternalFormat format) const
+{
+ switch (format)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return ImageFunction::DataType::FLOAT4;
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return ImageFunction::DataType::UINT4;
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return ImageFunction::DataType::INT4;
+ case EiifRGBA8:
+ return ImageFunction::DataType::UNORM_FLOAT4;
+ case EiifRGBA8_SNORM:
+ return ImageFunction::DataType::SNORM_FLOAT4;
+ default:
+ UNREACHABLE();
+ }
+
+ return ImageFunction::DataType::NONE;
+}
+
+const char *ImageFunctionHLSL::ImageFunction::getReturnType() const
+{
+ if (method == ImageFunction::Method::SIZE)
+ {
+ switch (image)
+ {
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ return "int2";
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ return "int3";
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return "int";
+ default:
+ UNREACHABLE();
+ }
+ }
+ else if (method == ImageFunction::Method::LOAD)
+ {
+ switch (image)
+ {
+ case EbtImageBuffer:
+ case EbtImage2D:
+ case EbtImage3D:
+ case EbtImageCube:
+ case EbtImage2DArray:
+ return "float4";
+ case EbtIImageBuffer:
+ case EbtIImage2D:
+ case EbtIImage3D:
+ case EbtIImageCube:
+ case EbtIImage2DArray:
+ return "int4";
+ case EbtUImageBuffer:
+ case EbtUImage2D:
+ case EbtUImage3D:
+ case EbtUImageCube:
+ case EbtUImage2DArray:
+ return "uint4";
+ default:
+ UNREACHABLE();
+ }
+ }
+ else if (method == ImageFunction::Method::STORE)
+ {
+ return "void";
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ return "";
+}
+
+bool ImageFunctionHLSL::ImageFunction::operator<(const ImageFunction &rhs) const
+{
+ return std::tie(image, type, method, readonly) <
+ std::tie(rhs.image, rhs.type, rhs.method, rhs.readonly);
+}
+
+ImmutableString ImageFunctionHLSL::useImageFunction(const ImmutableString &name,
+ const TBasicType &type,
+ TLayoutImageInternalFormat imageInternalFormat,
+ bool readonly)
+{
+ ASSERT(IsImage(type));
+ ImageFunction imageFunction;
+ imageFunction.image = type;
+ imageFunction.imageInternalFormat = imageInternalFormat;
+ imageFunction.readonly = readonly;
+ imageFunction.type = imageFunction.getDataType(imageInternalFormat);
+
+ if (name == "imageSize")
+ {
+ imageFunction.method = ImageFunction::Method::SIZE;
+ }
+ else if (name == "imageLoad")
+ {
+ imageFunction.method = ImageFunction::Method::LOAD;
+ }
+ else if (name == "imageStore")
+ {
+ imageFunction.method = ImageFunction::Method::STORE;
+ }
+ else
+ UNREACHABLE();
+
+ mUsesImage.insert(imageFunction);
+ return imageFunction.name();
+}
+
+void ImageFunctionHLSL::imageFunctionHeader(TInfoSinkBase &out)
+{
+ for (const ImageFunction &imageFunction : mUsesImage)
+ {
+ // Skip to generate image2D functions here, dynamically generate these
+ // functions when linking, or after dispatch or draw.
+ if (IsImage2D(imageFunction.image))
+ {
+ mUsedImage2DFunctionNames.insert(imageFunction.name().data());
+ continue;
+ }
+ // Function header
+ out << imageFunction.getReturnType() << " " << imageFunction.name() << "(";
+
+ OutputImageFunctionArgumentList(out, imageFunction);
+
+ out << ")\n"
+ "{\n";
+
+ ImmutableString imageReference = GetImageReference(out, imageFunction);
+ if (imageFunction.method == ImageFunction::Method::SIZE)
+ {
+ OutputImageSizeFunctionBody(out, imageFunction, imageReference);
+ }
+ else if (imageFunction.method == ImageFunction::Method::LOAD)
+ {
+ OutputImageLoadFunctionBody(out, imageFunction, imageReference);
+ }
+ else
+ {
+ OutputImageStoreFunctionBody(out, imageFunction, imageReference);
+ }
+
+ out << "}\n"
+ "\n";
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.h b/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.h
new file mode 100644
index 0000000000..12a4a9de27
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.h
@@ -0,0 +1,96 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ImageFunctionHLSL: Class for writing implementations of ESSL image functions into HLSL output.
+//
+
+#ifndef COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_
+#define COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_
+
+#include <set>
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+class ImageFunctionHLSL final : angle::NonCopyable
+{
+ public:
+ // Returns the name of the image function implementation to caller.
+ // The name that's passed in is the name of the GLSL image function that it should implement.
+ ImmutableString useImageFunction(const ImmutableString &name,
+ const TBasicType &type,
+ TLayoutImageInternalFormat imageInternalFormat,
+ bool readonly);
+
+ void imageFunctionHeader(TInfoSinkBase &out);
+ const std::set<std::string> &getUsedImage2DFunctionNames() const
+ {
+ return mUsedImage2DFunctionNames;
+ }
+
+ private:
+ struct ImageFunction
+ {
+ // See ESSL 3.10.4 section 8.12 for reference about what the different methods below do.
+ enum class Method
+ {
+ SIZE,
+ LOAD,
+ STORE
+ };
+
+ enum class DataType
+ {
+ NONE,
+ FLOAT4,
+ UINT4,
+ INT4,
+ UNORM_FLOAT4,
+ SNORM_FLOAT4
+ };
+
+ ImmutableString name() const;
+
+ bool operator<(const ImageFunction &rhs) const;
+
+ DataType getDataType(TLayoutImageInternalFormat format) const;
+
+ const char *getReturnType() const;
+
+ TBasicType image;
+ TLayoutImageInternalFormat imageInternalFormat;
+ bool readonly;
+ Method method;
+ DataType type;
+ };
+
+ static ImmutableString GetImageReference(TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction);
+ static void OutputImageFunctionArgumentList(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction);
+ static void OutputImageSizeFunctionBody(TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference);
+ static void OutputImageLoadFunctionBody(TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference);
+ static void OutputImageStoreFunctionBody(TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference);
+ using ImageFunctionSet = std::set<ImageFunction>;
+ ImageFunctionSet mUsesImage;
+ std::set<std::string> mUsedImage2DFunctionNames;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ImmutableString.h b/gfx/angle/checkout/src/compiler/translator/ImmutableString.h
new file mode 100644
index 0000000000..f172708d7d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImmutableString.h
@@ -0,0 +1,143 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ImmutableString.h: Wrapper for static or pool allocated char arrays, that are guaranteed to be
+// valid and unchanged for the duration of the compilation.
+//
+
+#ifndef COMPILER_TRANSLATOR_IMMUTABLESTRING_H_
+#define COMPILER_TRANSLATOR_IMMUTABLESTRING_H_
+
+#include <string>
+
+#include "common/string_utils.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr size_t constStrlen(const char *str)
+{
+ if (str == nullptr)
+ {
+ return 0u;
+ }
+ size_t len = 0u;
+ while (*(str + len) != '\0')
+ {
+ ++len;
+ }
+ return len;
+}
+} // namespace
+
+class ImmutableString
+{
+ public:
+ // The data pointer passed in must be one of:
+ // 1. nullptr (only valid with length 0).
+ // 2. a null-terminated static char array like a string literal.
+ // 3. a null-terminated pool allocated char array. This can't be c_str() of a local TString,
+ // since when a TString goes out of scope it clears its first character.
+ explicit constexpr ImmutableString(const char *data) : mData(data), mLength(constStrlen(data))
+ {}
+
+ constexpr ImmutableString(const char *data, size_t length) : mData(data), mLength(length) {}
+
+ ImmutableString(const std::string &str)
+ : mData(AllocatePoolCharArray(str.c_str(), str.size())), mLength(str.size())
+ {}
+
+ constexpr ImmutableString(const ImmutableString &) = default;
+
+ ImmutableString &operator=(const ImmutableString &) = default;
+
+ constexpr const char *data() const { return mData ? mData : ""; }
+ constexpr size_t length() const { return mLength; }
+
+ char operator[](size_t index) const { return data()[index]; }
+
+ constexpr bool empty() const { return mLength == 0; }
+ bool beginsWith(const char *prefix) const { return angle::BeginsWith(data(), prefix); }
+ constexpr bool beginsWith(const ImmutableString &prefix) const
+ {
+ return mLength >= prefix.length() && memcmp(data(), prefix.data(), prefix.length()) == 0;
+ }
+ bool contains(const char *substr) const { return strstr(data(), substr) != nullptr; }
+
+ constexpr bool operator==(const ImmutableString &b) const
+ {
+ if (mLength != b.mLength)
+ {
+ return false;
+ }
+ return memcmp(data(), b.data(), mLength) == 0;
+ }
+ constexpr bool operator!=(const ImmutableString &b) const { return !(*this == b); }
+ constexpr bool operator==(const char *b) const
+ {
+ if (b == nullptr)
+ {
+ return empty();
+ }
+ return strcmp(data(), b) == 0;
+ }
+ constexpr bool operator!=(const char *b) const { return !(*this == b); }
+ bool operator==(const std::string &b) const
+ {
+ return mLength == b.length() && memcmp(data(), b.c_str(), mLength) == 0;
+ }
+ bool operator!=(const std::string &b) const { return !(*this == b); }
+
+ constexpr bool operator<(const ImmutableString &b) const
+ {
+ if (mLength < b.mLength)
+ {
+ return true;
+ }
+ if (mLength > b.mLength)
+ {
+ return false;
+ }
+ return (memcmp(data(), b.data(), mLength) < 0);
+ }
+
+ template <size_t hashBytes>
+ struct FowlerNollVoHash
+ {
+ static const size_t kFnvOffsetBasis;
+ static const size_t kFnvPrime;
+
+ constexpr size_t operator()(const ImmutableString &a) const
+ {
+ const char *data = a.data();
+ size_t hash = kFnvOffsetBasis;
+ while ((*data) != '\0')
+ {
+ hash = hash ^ (*data);
+ hash = hash * kFnvPrime;
+ ++data;
+ }
+ return hash;
+ }
+ };
+
+ // Perfect hash functions
+ uint32_t mangledNameHash() const;
+ uint32_t unmangledNameHash() const;
+
+ private:
+ const char *mData;
+ size_t mLength;
+};
+
+constexpr ImmutableString kEmptyImmutableString("");
+} // namespace sh
+
+std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str);
+
+#endif // COMPILER_TRANSLATOR_IMMUTABLESTRING_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.cpp b/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.cpp
new file mode 100644
index 0000000000..3c7c01041f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.cpp
@@ -0,0 +1,63 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ImmutableStringBuilder.cpp: Stringstream-like utility for building pool allocated strings where
+// the maximum length is known in advance.
+//
+
+#include "compiler/translator/ImmutableStringBuilder.h"
+
+#include <stdio.h>
+
+namespace sh
+{
+
+ImmutableStringBuilder &ImmutableStringBuilder::operator<<(const ImmutableString &str)
+{
+ ASSERT(mData != nullptr);
+ ASSERT(mPos + str.length() <= mMaxLength);
+ memcpy(mData + mPos, str.data(), str.length());
+ mPos += str.length();
+ return *this;
+}
+
+ImmutableStringBuilder &ImmutableStringBuilder::operator<<(const char *str)
+{
+ ASSERT(mData != nullptr);
+ size_t len = strlen(str);
+ ASSERT(mPos + len <= mMaxLength);
+ memcpy(mData + mPos, str, len);
+ mPos += len;
+ return *this;
+}
+
+ImmutableStringBuilder &ImmutableStringBuilder::operator<<(const char &c)
+{
+ ASSERT(mData != nullptr);
+ ASSERT(mPos + 1 <= mMaxLength);
+ mData[mPos++] = c;
+ return *this;
+}
+
+void ImmutableStringBuilder::appendDecimal(const uint32_t &u)
+{
+ int numChars = snprintf(mData + mPos, mMaxLength - mPos, "%d", u);
+ ASSERT(numChars >= 0);
+ ASSERT(mPos + numChars <= mMaxLength);
+ mPos += numChars;
+}
+
+ImmutableStringBuilder::operator ImmutableString()
+{
+ mData[mPos] = '\0';
+ ImmutableString str(static_cast<const char *>(mData), mPos);
+#if defined(ANGLE_ENABLE_ASSERTS)
+ // Make sure that nothing is added to the string after it is finalized.
+ mData = nullptr;
+#endif
+ return str;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h b/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h
new file mode 100644
index 0000000000..2af963821c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h
@@ -0,0 +1,80 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ImmutableStringBuilder.h: Stringstream-like utility for building pool allocated strings where the
+// maximum length is known in advance.
+//
+
+#ifndef COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_
+#define COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_
+
+#include "compiler/translator/ImmutableString.h"
+
+namespace sh
+{
+
+class ImmutableStringBuilder
+{
+ public:
+ ImmutableStringBuilder(size_t maxLength)
+ : mPos(0u), mMaxLength(maxLength), mData(AllocateEmptyPoolCharArray(maxLength))
+ {}
+
+ ImmutableStringBuilder &operator<<(const ImmutableString &str);
+
+ ImmutableStringBuilder &operator<<(const char *str);
+
+ ImmutableStringBuilder &operator<<(const char &c);
+
+ // This invalidates the ImmutableStringBuilder, so it should only be called once.
+ operator ImmutableString();
+
+ void appendDecimal(const uint32_t &i);
+
+ template <typename T>
+ void appendHex(T number)
+ {
+ ASSERT(mData != nullptr);
+ ASSERT(mPos + sizeof(T) * 2u <= mMaxLength);
+ int index = static_cast<int>(sizeof(T)) * 2 - 1;
+ // Loop through leading zeroes.
+ while (((number >> (index * 4)) & 0xfu) == 0 && index > 0)
+ {
+ --index;
+ }
+ // Write the rest of the hex digits.
+ while (index >= 0)
+ {
+ char digit = static_cast<char>((number >> (index * 4)) & 0xfu);
+ char digitChar = (digit < 10) ? (digit + '0') : (digit + ('a' - 10));
+ mData[mPos++] = digitChar;
+ --index;
+ }
+ }
+
+ template <typename T>
+ static constexpr size_t GetHexCharCount()
+ {
+ return sizeof(T) * 2;
+ }
+
+ private:
+ inline static char *AllocateEmptyPoolCharArray(size_t strLength)
+ {
+ size_t requiredSize = strLength + 1u;
+ return static_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize));
+ }
+
+ size_t mPos;
+ size_t mMaxLength;
+ char *mData;
+};
+
+// GLSL ES 3.00.6 section 3.9: the maximum length of an identifier is 1024 characters.
+constexpr unsigned int kESSLMaxIdentifierLength = 1024u;
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ImmutableString_ESSL_autogen.cpp b/gfx/angle/checkout/src/compiler/translator/ImmutableString_ESSL_autogen.cpp
new file mode 100644
index 0000000000..6199adb2b4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImmutableString_ESSL_autogen.cpp
@@ -0,0 +1,345 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ImmutableString_ESSL_autogen.cpp: Wrapper for static or pool allocated char arrays, that are
+// guaranteed to be valid and unchanged for the duration of the compilation. Implements
+// mangledNameHash using perfect hash function from gen_builtin_symbols.py
+
+#include "compiler/translator/ImmutableString.h"
+
+std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str)
+{
+ return os.write(str.data(), str.length());
+}
+
+#if defined(_MSC_VER)
+# pragma warning(disable : 4309) // truncation of constant value
+#endif
+
+namespace
+{
+
+constexpr int mangledkT1[] = {3297, 2629, 2651, 2337, 2303, 3220, 3385, 1210, 2130, 1919,
+ 3300, 2529, 2310, 3215, 1751, 2155, 96, 2644, 3105, 1639,
+ 1010, 851, 1501, 558, 2641, 328, 1973, 296, 1999, 2273,
+ 441, 2860, 911, 1153, 2602, 1727, 2732, 521, 1672, 1330};
+constexpr int mangledkT2[] = {1661, 42, 548, 942, 2329, 3201, 841, 3274, 1976, 3379,
+ 1752, 1024, 961, 2388, 3033, 1547, 591, 2585, 1383, 473,
+ 319, 3081, 1789, 734, 478, 219, 1353, 381, 1660, 408,
+ 1440, 2281, 2126, 1243, 1080, 2835, 3286, 168, 458, 1343};
+constexpr int mangledkG[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1017, 0, 0, 2710, 0, 0, 0,
+ 0, 0, 2927, 578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2927, 632, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1534, 0, 0, 0, 1494, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3388, 0, 0, 0, 0, 575, 0, 1229, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2918, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0,
+ 1595, 0, 0, 0, 3263, 0, 3229, 372, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3123, 0, 0, 900, 0, 0,
+ 0, 459, 0, 0, 0, 0, 0, 0, 2582, 1333, 0, 172, 126, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2180, 0, 841, 0, 0, 0, 2145, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 954, 0, 811, 0, 0, 0, 677, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1862, 2279, 0, 2634, 0, 0, 2477, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2784, 0, 0, 0, 3384, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2761, 0, 0, 0, 1572, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 905,
+ 0, 0, 0, 3350, 0, 0, 0, 0, 1371, 2614, 0, 0, 3227, 0, 0, 0,
+ 1772, 0, 601, 0, 944, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1928,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2236, 0, 0, 0, 3179, 0, 0, 619,
+ 0, 0, 3251, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 1825,
+ 0, 0, 0, 0, 3177, 2489, 0, 0, 70, 0, 519, 0, 505, 1676, 0, 0,
+ 0, 0, 0, 1871, 0, 0, 2289, 0, 0, 0, 1192, 0, 2362, 776, 2964, 0,
+ 0, 0, 2478, 0, 1303, 0, 96, 0, 0, 3408, 0, 0, 0, 2894, 250, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2894, 0, 3389, 930, 2489, 0, 2755, 0, 1807,
+ 701, 2938, 0, 0, 0, 0, 609, 0, 0, 0, 1985, 343, 0, 2608, 0, 368,
+ 1367, 1387, 0, 0, 3160, 0, 0, 0, 2036, 0, 0, 2231, 0, 0, 2248, 2652,
+ 0, 306, 0, 0, 3308, 0, 0, 0, 525, 0, 0, 1300, 0, 0, 1432, 2594,
+ 2612, 53, 1093, 0, 1779, 3020, 3237, 458, 47, 0, 0, 526, 1378, 0, 0, 0,
+ 442, 1063, 3293, 0, 0, 0, 0, 0, 0, 832, 2958, 1452, 0, 0, 349, 0,
+ 1871, 0, 0, 2548, 1826, 441, 2846, 0, 2601, 1910, 1415, 0, 0, 0, 420, 0,
+ 3073, 620, 0, 0, 1333, 1133, 0, 0, 1402, 0, 0, 0, 0, 292, 0, 0,
+ 0, 0, 0, 1598, 364, 0, 1161, 0, 0, 0, 0, 218, 0, 2572, 226, 0,
+ 527, 270, 2558, 2814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1796, 0,
+ 0, 173, 610, 2959, 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1954, 0, 0, 0, 0, 414, 0, 0, 0, 0, 0, 0, 0, 265,
+ 0, 0, 0, 0, 230, 0, 502, 0, 1243, 0, 0, 2474, 0, 0, 0, 0,
+ 23, 0, 668, 0, 3125, 0, 3209, 0, 0, 928, 402, 0, 39, 117, 443, 852,
+ 0, 767, 0, 0, 0, 0, 3067, 0, 0, 0, 1532, 0, 0, 0, 3202, 0,
+ 0, 0, 0, 0, 2801, 0, 2221, 0, 0, 3, 0, 0, 0, 0, 0, 3241,
+ 1620, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 665, 0, 0, 1803, 0,
+ 2475, 0, 0, 0, 499, 0, 1386, 3147, 0, 0, 1168, 0, 0, 0, 1824, 0,
+ 0, 78, 935, 136, 0, 0, 882, 0, 0, 421, 257, 381, 0, 0, 643, 0,
+ 0, 284, 0, 2581, 0, 0, 0, 0, 0, 0, 963, 0, 0, 0, 3217, 681,
+ 479, 0, 529, 0, 0, 0, 0, 0, 2901, 0, 1026, 0, 1190, 0, 0, 0,
+ 0, 0, 0, 3265, 0, 0, 2287, 0, 0, 0, 0, 594, 0, 0, 0, 0,
+ 0, 114, 0, 608, 0, 2750, 0, 3179, 0, 161, 0, 0, 0, 556, 3087, 2490,
+ 1878, 0, 0, 0, 0, 2550, 0, 0, 0, 0, 0, 1638, 0, 746, 0, 0,
+ 338, 0, 1430, 0, 0, 1407, 0, 1134, 0, 0, 0, 0, 0, 0, 0, 0,
+ 113, 227, 0, 433, 927, 0, 0, 0, 1526, 1343, 38, 0, 2017, 1986, 3079, 0,
+ 3409, 0, 0, 0, 0, 2612, 1300, 138, 0, 0, 2020, 486, 0, 0, 1627, 0,
+ 0, 209, 0, 2406, 563, 97, 0, 578, 0, 0, 1064, 0, 1394, 61, 1962, 1613,
+ 534, 134, 994, 0, 0, 3180, 0, 0, 0, 0, 0, 0, 0, 1648, 0, 0,
+ 0, 0, 0, 0, 0, 2627, 0, 0, 955, 3301, 0, 414, 395, 0, 467, 681,
+ 0, 0, 0, 3070, 747, 1612, 0, 2987, 429, 0, 0, 438, 0, 627, 2229, 0,
+ 0, 0, 0, 0, 0, 2486, 35, 0, 307, 450, 0, 0, 0, 0, 0, 3382,
+ 2994, 3119, 0, 992, 1257, 781, 1249, 0, 915, 981, 837, 3177, 0, 0, 0, 0,
+ 748, 0, 0, 66, 3212, 0, 0, 3142, 0, 311, 744, 767, 0, 0, 0, 0,
+ 0, 0, 1164, 0, 1138, 757, 67, 1332, 724, 2680, 0, 0, 0, 275, 1321, 0,
+ 0, 750, 1072, 0, 660, 1228, 546, 0, 543, 0, 0, 0, 0, 1429, 356, 0,
+ 1200, 0, 0, 914, 1270, 0, 149, 474, 936, 336, 2834, 0, 0, 0, 0, 0,
+ 93, 0, 0, 0, 588, 0, 2776, 0, 1485, 0, 3193, 1133, 0, 0, 1386, 0,
+ 0, 0, 435, 87, 0, 0, 679, 1588, 321, 0, 0, 0, 2574, 0, 0, 0,
+ 0, 1079, 156, 0, 0, 582, 0, 793, 3388, 2758, 2508, 2915, 0, 0, 1326, 925,
+ 2685, 0, 0, 3305, 0, 469, 0, 1874, 120, 0, 0, 0, 0, 567, 549, 0,
+ 1237, 0, 0, 0, 2254, 0, 0, 1747, 348, 0, 0, 0, 2774, 0, 0, 0,
+ 0, 572, 0, 0, 1785, 251, 0, 767, 0, 3365, 0, 586, 1354, 0, 1039, 0,
+ 0, 625, 0, 0, 34, 2733, 0, 888, 522, 0, 518, 0, 2166, 0, 1502, 2652,
+ 0, 1277, 2808, 0, 1369, 1428, 0, 0, 0, 711, 0, 159, 1118, 0, 0, 0,
+ 248, 996, 2274, 0, 537, 2856, 0, 0, 0, 0, 0, 0, 2313, 769, 0, 0,
+ 0, 1145, 0, 0, 0, 0, 0, 0, 0, 0, 1582, 1138, 0, 0, 0, 967,
+ 1194, 0, 273, 1590, 459, 0, 0, 1620, 0, 0, 0, 1331, 0, 661, 0, 0,
+ 339, 0, 1582, 807, 0, 0, 1082, 0, 0, 0, 0, 0, 0, 0, 293, 0,
+ 1065, 1277, 0, 0, 949, 916, 36, 867, 0, 1335, 1355, 0, 997, 1273, 0, 0,
+ 0, 1508, 0, 0, 1632, 896, 0, 3338, 0, 1280, 1145, 278, 0, 1361, 2064, 1030,
+ 0, 435, 0, 0, 384, 2984, 0, 0, 0, 0, 909, 0, 0, 0, 149, 539,
+ 2604, 0, 463, 1583, 554, 1663, 0, 446, 0, 0, 0, 1075, 0, 2395, 0, 82,
+ 258, 0, 580, 0, 0, 549, 1508, 0, 1160, 0, 108, 195, 0, 136, 0, 704,
+ 0, 0, 3108, 0, 0, 0, 1625, 0, 359, 986, 3338, 1596, 1316, 47, 718, 479,
+ 560, 0, 33, 0, 879, 0, 0, 3021, 0, 616, 342, 0, 882, 776, 3251, 0,
+ 32, 513, 273, 232, 745, 1184, 0, 3288, 364, 0, 0, 3102, 0, 3193, 481, 0,
+ 842, 0, 3113, 647, 0, 0, 0, 2239, 0, 720, 0, 1193, 0, 980, 0, 0,
+ 0, 0, 661, 1493, 3369, 3348, 31, 1970, 0, 1251, 1513, 0, 0, 2199, 673, 562,
+ 33, 186, 1457, 0, 788, 0, 1036, 0, 0, 1998, 0, 0, 0, 1906, 0, 1148,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1047, 980, 0, 1363, 0, 0, 2893,
+ 0, 0, 0, 1442, 0, 0, 2735, 1044, 0, 0, 1197, 0, 434, 0, 420, 1008,
+ 3104, 0, 2979, 823, 0, 0, 0, 98, 2814, 1534, 2319, 996, 2897, 0, 0, 2194,
+ 961, 0, 0, 1551, 0, 0, 0, 0, 0, 0, 0, 0, 565, 2808, 0, 1868,
+ 667, 0, 0, 0, 0, 1017, 139, 0, 0, 0, 154, 0, 3155, 0, 769, 2996,
+ 1247, 1113, 0, 0, 3203, 0, 1183, 0, 1469, 0, 1193, 375, 88, 0, 0, 0,
+ 0, 0, 0, 1037, 0, 3370, 180, 1947, 0, 0, 0, 2759, 2065, 0, 0, 0,
+ 3345, 564, 0, 2730, 0, 2979, 0, 5, 0, 2986, 155, 0, 393, 1884, 1845, 0,
+ 0, 2673, 0, 453, 945, 123, 1252, 0, 550, 1599, 231, 150, 1215, 0, 233, 3394,
+ 3370, 455, 0, 1620, 0, 0, 2860, 0, 1569, 0, 2095, 0, 1392, 0, 0, 373,
+ 0, 388, 0, 0, 2856, 2919, 2416, 0, 0, 0, 0, 0, 0, 933, 2108, 0,
+ 1536, 666, 675, 495, 0, 1705, 0, 0, 656, 0, 0, 63, 1484, 0, 0, 1033,
+ 0, 914, 3397, 0, 2927, 193, 597, 2666, 0, 1035, 0, 0, 0, 0, 1726, 1719,
+ 3405, 0, 0, 1644, 0, 0, 555, 0, 58, 1168, 0, 430, 236, 997, 935, 0,
+ 0, 659, 402, 3243, 0, 1010, 0, 2241, 0, 1140, 2556, 0, 1002, 748, 539, 213,
+ 0, 1602, 263, 0, 0, 0, 1286, 669, 333, 2327, 0, 0, 911, 0, 157, 716,
+ 0, 0, 0, 0, 180, 0, 0, 0, 359, 0, 3042, 0, 0, 808, 982, 732,
+ 1539, 0, 324, 0, 0, 0, 0, 3325, 698, 0, 1799, 0, 2942, 2667, 0, 519,
+ 2898, 1068, 0, 0, 0, 1460, 3022, 0, 0, 0, 2842, 927, 3152, 0, 0, 1521,
+ 1362, 0, 0, 588, 0, 34, 2910, 0, 0, 0, 2621, 0, 2712, 315, 2628, 0,
+ 286, 718, 0, 267, 775, 76, 0, 0, 0, 0, 0, 0, 0, 3229, 0, 1924,
+ 0, 0, 0, 0, 1454, 1384, 2952, 0, 0, 154, 0, 0, 0, 271, 0, 0,
+ 289, 179, 2419, 2348, 0, 766, 0, 1462, 2514, 930, 768, 0, 0, 0, 0, 0,
+ 0, 0, 331, 1380, 0, 1161, 0, 0, 3313, 0, 3367, 0, 0, 0, 0, 0,
+ 1147, 0, 1866, 0, 0, 1649, 0, 0, 0, 858, 964, 0, 1975, 0, 0, 0,
+ 0, 1031, 0, 0, 2901, 3008, 0, 0, 2440, 1174, 910, 1006, 3125, 0, 2724, 825,
+ 0, 2250, 1465, 0, 0, 0, 1104, 476, 1673, 0, 1429, 130, 1183, 1909, 183, 650,
+ 487, 0, 0, 676, 0, 1528, 0, 0, 426, 2746, 731, 0, 0, 1225, 0, 0,
+ 662, 2458, 0, 2203, 0, 0, 998, 0, 3016, 223, 0, 2759, 1006, 0, 0, 3356,
+ 1197, 0, 0, 1165, 940, 1424, 365, 1120, 0, 0, 0, 0, 838, 0, 2166, 0,
+ 1592, 2396, 859, 1542, 0, 0, 0, 406, 0, 1468, 1315, 3385, 186, 672, 3019, 853,
+ 301, 2253, 1429, 1225, 845, 1067, 128, 0, 0, 1144, 0, 207, 0, 400, 0, 1051,
+ 0, 492, 0, 0, 0, 0, 283, 0, 161, 0, 2649, 1013, 0, 3075, 0, 62,
+ 2968, 1449, 0, 641, 2728, 0, 1912, 1170, 1553, 1466, 120, 0, 0, 812, 0, 188,
+ 0, 0, 1278, 3176, 0, 0, 0, 0, 2742, 0, 0, 1772, 0, 874, 680, 0,
+ 1378, 2733, 53, 0, 0, 329, 2, 1014, 2786, 719, 1868, 0, 2296, 0, 357, 0,
+ 0, 0, 0, 2371, 1203, 1109, 1302, 3047, 2319, 0, 2834, 1711, 0, 849, 1658, 131,
+ 0, 1191, 268, 1519, 0, 1080, 0, 0, 488, 0, 46, 0, 658, 0, 0, 1838,
+ 0, 0, 0, 0, 1741, 2096, 1701, 0, 0, 691, 3262, 950, 0, 0, 0, 704,
+ 734, 2177, 3260, 0, 0, 897, 291, 1318, 866, 3105, 3161, 1205, 0, 0, 0, 0,
+ 0, 0, 0, 835, 0, 0, 0, 0, 0, 0, 1283, 0, 0, 772, 0, 1482,
+ 1609, 1279, 1121, 870, 0, 3184, 818, 1521, 0, 0, 297, 0, 0, 1360, 0, 0,
+ 249, 0, 2112, 72, 0, 1110, 2278, 619, 0, 1014, 809, 397, 0, 0, 1406, 0,
+ 905, 0, 690, 751, 0, 0, 0, 19, 3355, 0, 0, 0, 0, 1345, 114, 945,
+ 0, 122, 173, 0, 133, 0, 971, 0, 453, 1183, 0, 0, 2729, 632, 678, 1572,
+ 0, 1304, 1433, 926, 0, 0, 302, 941, 0, 0, 0, 0, 0, 1222, 0, 0,
+ 0, 0, 1771, 0, 884, 872, 0, 0, 1234, 1928, 3190, 0, 0, 0, 0, 0,
+ 238, 615, 522, 287, 654, 798, 0, 1264, 0, 0, 0, 0, 466, 395, 1175, 1406,
+ 633, 1146, 3235, 3347, 62, 237, 0, 0, 0, 0, 0, 10, 1461, 0, 0, 1914,
+ 447, 0, 3148, 1253, 1970, 0, 1404, 744, 3377, 1362, 3085, 0, 3083, 1529, 0, 0,
+ 1441, 0, 1476, 0, 955, 156, 0, 0, 1753, 1212, 0, 45, 1193, 1605, 0, 0,
+ 0, 0, 209, 180, 447, 1584, 25, 1520, 2177, 0, 74, 0, 3334, 2718, 0, 728,
+ 0, 1000, 0, 1366, 978, 0, 0, 1488, 3222, 122, 388, 1642, 946, 0, 0, 0,
+ 0, 0, 741, 0, 0, 0, 0, 1875, 1116, 880, 0, 343, 1376, 0, 1700, 0,
+ 2350, 605, 132, 0, 0, 1430, 0, 0, 528, 564, 0, 1571, 1265, 0, 0, 625,
+ 3052, 1040, 1470, 266, 603, 3325, 0, 679, 0, 1902, 265, 2718, 1591, 671, 3356, 0,
+ 0, 321, 0, 3219, 990, 0, 408, 0, 716, 0, 0, 0, 823, 99, 754, 780,
+ 3334, 365, 0, 1681, 2332, 0, 3209, 0, 0, 774, 589, 0, 0, 841, 138, 679,
+ 320, 0, 0, 2355, 491, 3001, 0, 3280, 0, 0, 1743, 0, 0, 0, 2191, 0,
+ 1177, 0, 0, 0, 0, 0, 1143, 0, 0, 0, 580, 0, 0, 0, 0, 0,
+ 0, 620, 0, 1207, 0, 1603, 494, 433, 0, 847, 44, 2265, 2101, 2457, 0, 0,
+ 0, 389, 1429, 2257, 3104, 455, 0, 0, 0, 0, 0, 0, 1468, 966, 978, 1878,
+ 1217, 3122, 2407, 0, 3022, 0, 0, 910, 466, 0, 2931, 2770, 173, 209, 1004, 0,
+ 160, 0, 1405, 0, 965, 0, 0, 1455, 1314, 2643, 0, 713, 1544, 0, 0, 0,
+ 544, 0, 476, 847, 1029, 983, 231, 285, 2181, 0, 0, 513, 739, 336, 0, 1206,
+ 0, 3020, 492, 0, 0, 596, 0, 0, 1282, 0, 121, 0, 0, 667, 873, 0,
+ 0, 1015, 196, 0, 1390, 469, 563, 1091, 349, 0, 2300, 0, 0, 104, 0, 23,
+ 1619, 0, 1649, 0, 0, 499, 558, 0, 0, 0, 0, 0, 1089, 0, 2932, 473,
+ 700, 2599, 0, 3, 3365, 557, 1347, 1138, 380, 2427, 0, 1084, 0, 0, 0, 701,
+ 0, 0, 2747, 0, 0, 1481, 0, 2017, 1487, 0, 0, 0, 0, 0, 2867, 609,
+ 0, 1453, 1383, 0, 0, 489, 0, 663, 3399, 0, 0, 2629, 1525, 2947, 0, 1472,
+ 0, 0, 744, 14, 0, 2982, 639, 0, 741, 389, 0, 0, 795, 0, 527, 0,
+ 0, 0, 404, 768, 2738, 1877, 0, 900, 82, 0, 0, 967, 0, 573, 103, 0,
+ 0, 498, 2837, 0, 0, 0, 340, 1070, 0, 0, 1127, 0, 1028, 1166, 0, 0,
+ 0, 0, 1111, 0, 1238, 2206, 222, 0, 632, 0, 3368, 923, 433, 0, 705, 57,
+ 536, 1427, 0, 0, 1232, 101, 0, 0, 255, 1427, 828, 0, 160, 613, 2986, 0,
+ 1010, 0, 0, 0, 2915, 2185, 1519, 2988, 2817, 3387, 3090, 1538, 43, 0, 781, 0,
+ 0, 0, 0, 0, 804, 2815, 3088, 3021, 1095, 0, 0, 0, 0, 1285, 0, 0,
+ 244, 0, 713, 0, 899, 0, 0, 0, 142, 16, 0, 1655, 119, 22, 2957, 0,
+ 785, 2620, 666, 0, 263, 0, 2359, 1150, 0, 243, 0, 946, 988, 1510, 637, 1271,
+ 1038, 0, 2893, 0, 0, 938, 0, 0, 175, 0, 0, 0, 0, 0, 0, 277,
+ 0, 2910, 0, 0, 0, 0, 1516, 2054, 0, 3270, 0, 3088, 410, 0, 3203, 1216,
+ 0, 0, 0, 1076, 590, 141, 282, 0, 0, 193, 2844, 225, 2981, 0, 0, 555,
+ 0, 1054, 275, 0, 1142, 0, 504, 1045, 550, 0, 799, 188, 2264, 1137, 0, 298,
+ 2843, 3120, 3365, 0, 881, 1430, 2165, 2552, 0, 0, 2305, 0, 1944, 0, 2030, 606,
+ 3296, 3028, 274, 936, 3036, 1285, 642, 0, 116, 834, 0, 1485, 1322, 0, 1667, 0,
+ 697, 2746, 893, 1561, 1264, 102, 0, 0, 362, 1242, 142, 0, 225, 957, 1153, 117,
+ 0, 515, 0, 0, 1393, 365, 266, 834, 0, 1317, 0, 0, 2334, 0, 0, 0,
+ 0, 0, 0, 165, 1293, 526, 17, 0, 71, 0, 2986, 0, 808, 1195, 6, 1124,
+ 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 1511, 380, 0, 250,
+ 0, 2324, 771, 0, 195, 0, 393, 0, 2126, 258, 0, 21, 354, 0, 0, 198,
+ 0, 0, 514, 0, 0, 0, 0, 0, 0, 0, 0, 564, 1284, 0, 0, 735,
+ 2316, 1196, 831, 1279, 2599, 504, 0, 1174, 3177, 0, 1224, 1308, 574, 119, 1426, 1969,
+ 0, 197, 1029, 0, 860, 928, 0, 1114, 767, 2884, 0, 0, 492, 1549, 2358, 0,
+ 2878, 930, 581, 1368, 0, 1223, 0, 96, 0, 3313, 868, 0, 2962, 2697, 2823, 1086,
+ 3239, 448, 0, 0, 0, 1236, 0, 0, 1310, 886, 531, 0, 9, 0, 0, 293,
+ 0, 0, 2627, 3078, 3408, 1297, 883, 115, 0, 2906, 3009, 0, 1405, 1046, 1101, 0,
+ 1556, 1118, 1103, 0, 0, 2284, 434, 922, 0, 0, 941, 3194, 1069, 2741, 307, 668,
+ 2373, 3061, 945, 643, 0, 1503, 0, 561, 0, 618, 0, 1172, 3050, 3218, 0, 752,
+ 2992, 0, 0, 0, 0, 839, 1252, 348, 144, 0, 29, 1190, 441, 3202, 705, 2600,
+ 1516, 73, 472, 814, 3042, 360, 0, 3256, 0, 0, 0, 0, 0, 0, 1748, 1007,
+ 3384, 0, 0, 1412, 473, 0, 0, 1325, 0, 3170, 541, 0, 1066, 1126, 1215, 0,
+ 0, 624, 0, 1219, 0, 949, 0, 730, 1376, 2256, 733, 0, 1577, 0, 576, 1594,
+ 181, 0, 461, 3238, 1436, 0, 900, 2191, 0, 894, 698, 0, 777, 59, 845, 2941,
+ 0, 0, 1408, 0, 224, 0, 0, 0, 2322, 1129, 1511, 0, 870, 239, 3365, 0,
+ 918, 1107, 0, 2483, 0, 0, 0, 0, 0, 0, 235, 1152, 1300, 304, 0, 396,
+ 0, 0, 130, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 1554, 0, 0,
+ 394, 3180, 1050, 0, 1363, 861, 0, 1069, 1015, 0, 3146, 0, 1352, 0, 876, 1221,
+ 0, 325, 0, 0, 53, 107, 0, 2951, 0, 0, 310, 424, 49, 0, 0, 815,
+ 0, 749, 0, 3227, 1192, 2310, 1281, 3210, 0, 252, 380, 0, 514, 0, 1404, 908,
+ 0, 0, 300, 920, 0, 0, 2257, 1566, 0, 396, 558, 0, 0, 936, 0, 663,
+ 2840, 0, 0, 1325, 2928, 1798, 0, 2180, 1327, 568, 1585, 662, 0, 0, 0, 1910,
+ 976, 0, 58, 0, 0, 3353, 0, 0, 0, 2580, 2798, 3201, 1146, 1352, 0, 858,
+ 104, 0, 1668, 0, 3186, 781, 987, 0, 571, 193, 13, 415, 657, 52, 0, 0,
+ 333, 729, 207, 696, 0, 3378, 1198, 2332, 0, 1327, 1564, 1009, 0, 0, 0, 0,
+ 153, 2698, 89, 1114, 3368, 2898, 3117, 2837, 0, 2690, 0, 2278, 2025, 921, 3232, 0,
+ 0, 1036, 2620, 0, 0, 0, 0, 300, 0, 1075, 1668, 0, 0, 0, 3159, 0,
+ 3032, 0, 3083, 982, 1684, 0, 0, 0, 523, 0, 0, 0, 0, 0, 294, 0,
+ 434, 52, 2034, 0, 0, 497, 2951, 1499, 0, 1874, 0, 2853, 0, 3319, 442, 1411,
+ 0, 2945, 0, 1324, 251, 3096, 0, 723, 3150, 0, 0, 0, 0, 570, 0, 3295,
+ 1259, 0, 1395, 2545, 885, 1991, 1730, 1268, 2599, 0, 1289, 275, 0, 0, 113, 1835,
+ 885, 1259, 2295, 682, 0, 0, 932, 0, 286, 0, 0, 60, 864, 0, 0, 1483,
+ 0, 86, 587, 9, 459, 0, 1342, 0, 1287, 416, 14, 371, 0, 0, 507, 0,
+ 350, 2826, 0, 0, 0, 3293, 3183, 0, 238, 0, 1501, 2720, 0, 3107, 0, 2340,
+ 1602, 2599, 0, 314, 0, 0, 1062, 347, 0, 1546, 0, 0, 0, 0, 895, 158,
+ 217, 1351, 0, 0, 2160, 0, 0, 120, 755, 407, 2490, 305, 288, 0, 182, 745,
+ 0, 1666, 3220, 177, 0, 0, 958, 0, 0, 0, 0, 2293, 0, 0, 0, 503,
+ 0, 0, 0, 1256, 2600, 987, 2318, 529, 1617, 3147, 1601, 0, 3178, 2050, 569, 0,
+ 513, 0, 0, 689, 1308, 0, 0, 0, 0, 746, 0, 398, 2399, 1141, 0, 3356,
+ 214, 0, 0, 2903, 0, 431, 2902, 356, 1944, 1430, 1478, 6, 0, 0, 117, 0,
+ 2887, 2267};
+
+int MangledHashG(const char *key, const int *T)
+{
+ int sum = 0;
+
+ for (int i = 0; key[i] != '\0'; i++)
+ {
+ sum += T[i] * key[i];
+ sum %= 3410;
+ }
+ return mangledkG[sum];
+}
+
+int MangledPerfectHash(const char *key)
+{
+ if (strlen(key) > 40)
+ return 0;
+
+ return (MangledHashG(key, mangledkT1) + MangledHashG(key, mangledkT2)) % 3410;
+}
+
+constexpr int unmangledkT1[] = {258, 260, 73, 6, 294, 235, 86, 89, 66, 164, 215,
+ 28, 84, 215, 207, 246, 53, 166, 227, 83, 238, 195,
+ 109, 294, 270, 27, 167, 281, 55, 194, 257, 4};
+constexpr int unmangledkT2[] = {67, 64, 203, 266, 212, 293, 215, 33, 106, 81, 61,
+ 214, 272, 162, 248, 114, 4, 202, 197, 98, 169, 304,
+ 196, 197, 294, 217, 1, 201, 74, 46, 38, 221};
+constexpr int unmangledkG[] = {
+ 0, 0, 0, 0, 132, 0, 0, 123, 0, 152, 0, 87, 196, 305, 0, 0, 229, 273,
+ 130, 0, 87, 27, 163, 284, 0, 0, 0, 179, 233, 88, 0, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 126, 0, 104, 0, 222, 0, 0, 0,
+ 0, 0, 171, 36, 129, 0, 0, 0, 113, 0, 142, 303, 0, 138, 246, 0, 21, 0,
+ 121, 0, 162, 0, 0, 0, 0, 0, 147, 205, 0, 0, 232, 19, 0, 200, 0, 0,
+ 0, 68, 277, 68, 63, 0, 31, 0, 0, 255, 0, 0, 122, 0, 0, 108, 1, 63,
+ 74, 20, 130, 0, 0, 284, 0, 98, 158, 245, 0, 22, 2, 157, 195, 0, 257, 0,
+ 0, 0, 2, 172, 0, 0, 0, 0, 0, 132, 0, 0, 72, 27, 35, 269, 224, 0,
+ 216, 45, 151, 44, 9, 21, 0, 0, 188, 0, 229, 132, 212, 0, 75, 279, 119, 0,
+ 0, 0, 261, 25, 3, 180, 0, 0, 42, 40, 133, 200, 51, 0, 0, 232, 137, 128,
+ 9, 0, 0, 0, 278, 0, 0, 100, 0, 0, 0, 11, 137, 0, 0, 6, 0, 97,
+ 63, 0, 0, 166, 86, 0, 43, 228, 0, 0, 88, 272, 242, 61, 25, 99, 0, 260,
+ 169, 0, 0, 0, 99, 123, 39, 289, 77, 83, 0, 0, 33, 167, 0, 305, 0, 230,
+ 22, 0, 284, 0, 85, 26, 0, 80, 0, 0, 19, 206, 266, 0, 292, 74, 233, 86,
+ 218, 0, 63, 104, 15, 0, 0, 26, 132, 303, 0, 155, 256, 0, 109, 0, 215, 52,
+ 0, 0, 155, 95, 240, 112, 0, 95, 54, 89, 0, 171, 0, 158, 0, 51, 23, 125,
+ 276, 16, 107, 177, 92, 113, 32, 45, 136, 0, 0, 90, 241, 279, 38, 185, 0, 169};
+
+int UnmangledHashG(const char *key, const int *T)
+{
+ int sum = 0;
+
+ for (int i = 0; key[i] != '\0'; i++)
+ {
+ sum += T[i] * key[i];
+ sum %= 306;
+ }
+ return unmangledkG[sum];
+}
+
+int UnmangledPerfectHash(const char *key)
+{
+ if (strlen(key) > 32)
+ return 0;
+
+ return (UnmangledHashG(key, unmangledkT1) + UnmangledHashG(key, unmangledkT2)) % 306;
+}
+
+} // namespace
+
+namespace sh
+{
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<4>::kFnvPrime = 16777619u;
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<4>::kFnvOffsetBasis = 0x811c9dc5u;
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<8>::kFnvPrime =
+ static_cast<size_t>(1099511628211ull);
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<8>::kFnvOffsetBasis =
+ static_cast<size_t>(0xcbf29ce484222325ull);
+
+uint32_t ImmutableString::mangledNameHash() const
+{
+ return MangledPerfectHash(data());
+}
+
+uint32_t ImmutableString::unmangledNameHash() const
+{
+ return UnmangledPerfectHash(data());
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/InfoSink.cpp b/gfx/angle/checkout/src/compiler/translator/InfoSink.cpp
new file mode 100644
index 0000000000..0e67d7324e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/InfoSink.cpp
@@ -0,0 +1,124 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/InfoSink.h"
+
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+void TInfoSinkBase::prefix(Severity severity)
+{
+ switch (severity)
+ {
+ case SH_WARNING:
+ sink.append("WARNING: ");
+ break;
+ case SH_ERROR:
+ sink.append("ERROR: ");
+ break;
+ default:
+ sink.append("UNKOWN ERROR: ");
+ break;
+ }
+}
+
+TInfoSinkBase &TInfoSinkBase::operator<<(const ImmutableString &str)
+{
+ sink.append(str.data());
+ return *this;
+}
+
+TInfoSinkBase &TInfoSinkBase::operator<<(const TType &type)
+{
+ if (type.isInvariant())
+ sink.append("invariant ");
+ if (type.getQualifier() != EvqTemporary && type.getQualifier() != EvqGlobal)
+ {
+ sink.append(type.getQualifierString());
+ sink.append(" ");
+ }
+ if (type.getPrecision() != EbpUndefined)
+ {
+ sink.append(type.getPrecisionString());
+ sink.append(" ");
+ }
+
+ const TMemoryQualifier &memoryQualifier = type.getMemoryQualifier();
+ if (memoryQualifier.readonly)
+ {
+ sink.append("readonly ");
+ }
+ if (memoryQualifier.writeonly)
+ {
+ sink.append("writeonly ");
+ }
+ if (memoryQualifier.coherent)
+ {
+ sink.append("coherent ");
+ }
+ if (memoryQualifier.restrictQualifier)
+ {
+ sink.append("restrict ");
+ }
+ if (memoryQualifier.volatileQualifier)
+ {
+ sink.append("volatile ");
+ }
+
+ if (type.isArray())
+ {
+ for (auto arraySizeIter = type.getArraySizes().rbegin();
+ arraySizeIter != type.getArraySizes().rend(); ++arraySizeIter)
+ {
+ *this << "array[" << (*arraySizeIter) << "] of ";
+ }
+ }
+ if (type.isMatrix())
+ {
+ *this << static_cast<uint32_t>(type.getCols()) << "X"
+ << static_cast<uint32_t>(type.getRows()) << " matrix of ";
+ }
+ else if (type.isVector())
+ *this << static_cast<uint32_t>(type.getNominalSize()) << "-component vector of ";
+
+ sink.append(type.getBasicString());
+
+ if (type.getStruct() != nullptr)
+ {
+ if (type.getStruct()->symbolType() == SymbolType::Empty)
+ {
+ *this << " <anonymous>";
+ }
+ else
+ {
+ *this << " '" << type.getStruct()->name() << "'";
+ }
+ if (type.isStructSpecifier())
+ {
+ *this << " (specifier)";
+ }
+ }
+
+ return *this;
+}
+
+void TInfoSinkBase::location(int file, int line)
+{
+ TPersistStringStream stream = sh::InitializeStream<TPersistStringStream>();
+ if (line)
+ stream << file << ":" << line;
+ else
+ stream << file << ":? ";
+ stream << ": ";
+
+ sink.append(stream.str());
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/InfoSink.h b/gfx/angle/checkout/src/compiler/translator/InfoSink.h
new file mode 100644
index 0000000000..bf6df8800c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/InfoSink.h
@@ -0,0 +1,152 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_INFOSINK_H_
+#define COMPILER_TRANSLATOR_INFOSINK_H_
+
+#include <math.h>
+#include <stdlib.h>
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/Severity.h"
+
+namespace sh
+{
+
+class ImmutableString;
+class TType;
+
+// Returns the fractional part of the given floating-point number.
+inline float fractionalPart(float f)
+{
+ float intPart = 0.0f;
+ return modff(f, &intPart);
+}
+
+class ImmutableString;
+
+//
+// Encapsulate info logs for all objects that have them.
+//
+// The methods are a general set of tools for getting a variety of
+// messages and types inserted into the log.
+//
+class TInfoSinkBase
+{
+ public:
+ TInfoSinkBase() {}
+
+ template <typename T>
+ TInfoSinkBase &operator<<(const T &t)
+ {
+ TPersistStringStream stream = sh::InitializeStream<TPersistStringStream>();
+ stream << t;
+ sink.append(stream.str());
+ return *this;
+ }
+ // Override << operator for specific types. It is faster to append strings
+ // and characters directly to the sink.
+ TInfoSinkBase &operator<<(char c)
+ {
+ sink.append(1, c);
+ return *this;
+ }
+ TInfoSinkBase &operator<<(const char *str)
+ {
+ sink.append(str);
+ return *this;
+ }
+ TInfoSinkBase &operator<<(const TPersistString &str)
+ {
+ sink.append(str);
+ return *this;
+ }
+ TInfoSinkBase &operator<<(const TString &str)
+ {
+ sink.append(str.c_str());
+ return *this;
+ }
+ TInfoSinkBase &operator<<(const ImmutableString &str);
+
+ TInfoSinkBase &operator<<(const TType &type);
+
+ // Make sure floats are written with correct precision.
+ TInfoSinkBase &operator<<(float f)
+ {
+ // Make sure that at least one decimal point is written. If a number
+ // does not have a fractional part, the default precision format does
+ // not write the decimal portion which gets interpreted as integer by
+ // the compiler.
+ TPersistStringStream stream = sh::InitializeStream<TPersistStringStream>();
+ if (fractionalPart(f) == 0.0f)
+ {
+ stream.precision(1);
+ stream << std::showpoint << std::fixed << f;
+ }
+ else
+ {
+ stream.unsetf(std::ios::fixed);
+ stream.unsetf(std::ios::scientific);
+ stream.precision(8);
+ stream << f;
+ }
+ sink.append(stream.str());
+ return *this;
+ }
+ // Write boolean values as their names instead of integral value.
+ TInfoSinkBase &operator<<(bool b)
+ {
+ const char *str = b ? "true" : "false";
+ sink.append(str);
+ return *this;
+ }
+
+ void erase()
+ {
+ sink.clear();
+ binarySink.clear();
+ }
+ int size() { return static_cast<int>(isBinary() ? binarySink.size() : sink.size()); }
+
+ const TPersistString &str() const
+ {
+ ASSERT(!isBinary());
+ return sink;
+ }
+ const char *c_str() const
+ {
+ ASSERT(!isBinary());
+ return sink.c_str();
+ }
+
+ void prefix(Severity severity);
+ void location(int file, int line);
+
+ bool isBinary() const { return !binarySink.empty(); }
+ void setBinary(BinaryBlob &&binary) { binarySink = std::move(binary); }
+ const BinaryBlob &getBinary() const
+ {
+ ASSERT(isBinary());
+ return binarySink;
+ }
+
+ private:
+ // The data in the info sink is either in human readable form (|sink|) or binary (|binarySink|).
+ TPersistString sink;
+ BinaryBlob binarySink;
+};
+
+class TInfoSink
+{
+ public:
+ TInfoSinkBase info;
+ TInfoSinkBase debug;
+ TInfoSinkBase obj;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_INFOSINK_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Initialize.cpp b/gfx/angle/checkout/src/compiler/translator/Initialize.cpp
new file mode 100644
index 0000000000..287765db8f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Initialize.cpp
@@ -0,0 +1,223 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/Initialize.h"
+
+namespace sh
+{
+
+void InitExtensionBehavior(const ShBuiltInResources &resources, TExtensionBehavior &extBehavior)
+{
+ if (resources.OES_standard_derivatives)
+ {
+ extBehavior[TExtension::OES_standard_derivatives] = EBhUndefined;
+ }
+ if (resources.OES_EGL_image_external)
+ {
+ extBehavior[TExtension::OES_EGL_image_external] = EBhUndefined;
+ }
+ if (resources.OES_EGL_image_external_essl3)
+ {
+ extBehavior[TExtension::OES_EGL_image_external_essl3] = EBhUndefined;
+ }
+ if (resources.NV_EGL_stream_consumer_external)
+ {
+ extBehavior[TExtension::NV_EGL_stream_consumer_external] = EBhUndefined;
+ }
+ if (resources.ARB_texture_rectangle)
+ {
+ // Special: ARB_texture_rectangle extension does not follow the standard for #extension
+ // directives - it is enabled by default. An extension directive may still disable it.
+ extBehavior[TExtension::ARB_texture_rectangle] = EBhEnable;
+ }
+ if (resources.EXT_blend_func_extended)
+ {
+ extBehavior[TExtension::EXT_blend_func_extended] = EBhUndefined;
+ }
+ if (resources.EXT_draw_buffers)
+ {
+ extBehavior[TExtension::EXT_draw_buffers] = EBhUndefined;
+ }
+ if (resources.EXT_frag_depth)
+ {
+ extBehavior[TExtension::EXT_frag_depth] = EBhUndefined;
+ }
+ if (resources.EXT_primitive_bounding_box)
+ {
+ extBehavior[TExtension::EXT_primitive_bounding_box] = EBhUndefined;
+ }
+ if (resources.OES_primitive_bounding_box)
+ {
+ extBehavior[TExtension::OES_primitive_bounding_box] = EBhUndefined;
+ }
+ if (resources.EXT_shader_texture_lod)
+ {
+ extBehavior[TExtension::EXT_shader_texture_lod] = EBhUndefined;
+ }
+ if (resources.EXT_shader_framebuffer_fetch)
+ {
+ extBehavior[TExtension::EXT_shader_framebuffer_fetch] = EBhUndefined;
+ }
+ if (resources.EXT_shader_framebuffer_fetch_non_coherent)
+ {
+ extBehavior[TExtension::EXT_shader_framebuffer_fetch_non_coherent] = EBhUndefined;
+ }
+ if (resources.NV_shader_framebuffer_fetch)
+ {
+ extBehavior[TExtension::NV_shader_framebuffer_fetch] = EBhUndefined;
+ }
+ if (resources.NV_shader_noperspective_interpolation)
+ {
+ extBehavior[TExtension::NV_shader_noperspective_interpolation] = EBhUndefined;
+ }
+ if (resources.ARM_shader_framebuffer_fetch)
+ {
+ extBehavior[TExtension::ARM_shader_framebuffer_fetch] = EBhUndefined;
+ }
+ if (resources.OVR_multiview)
+ {
+ extBehavior[TExtension::OVR_multiview] = EBhUndefined;
+ }
+ if (resources.OVR_multiview2)
+ {
+ extBehavior[TExtension::OVR_multiview2] = EBhUndefined;
+ }
+ if (resources.EXT_YUV_target)
+ {
+ extBehavior[TExtension::EXT_YUV_target] = EBhUndefined;
+ }
+ if (resources.EXT_geometry_shader)
+ {
+ extBehavior[TExtension::EXT_geometry_shader] = EBhUndefined;
+ }
+ if (resources.OES_geometry_shader)
+ {
+ extBehavior[TExtension::OES_geometry_shader] = EBhUndefined;
+ }
+ if (resources.OES_shader_io_blocks)
+ {
+ extBehavior[TExtension::OES_shader_io_blocks] = EBhUndefined;
+ }
+ if (resources.EXT_shader_io_blocks)
+ {
+ extBehavior[TExtension::EXT_shader_io_blocks] = EBhUndefined;
+ }
+ if (resources.EXT_gpu_shader5)
+ {
+ extBehavior[TExtension::EXT_gpu_shader5] = EBhUndefined;
+ }
+ if (resources.EXT_shader_non_constant_global_initializers)
+ {
+ extBehavior[TExtension::EXT_shader_non_constant_global_initializers] = EBhUndefined;
+ }
+ if (resources.OES_texture_storage_multisample_2d_array)
+ {
+ extBehavior[TExtension::OES_texture_storage_multisample_2d_array] = EBhUndefined;
+ }
+ if (resources.OES_texture_3D)
+ {
+ extBehavior[TExtension::OES_texture_3D] = EBhUndefined;
+ }
+ if (resources.ANGLE_shader_pixel_local_storage)
+ {
+ extBehavior[TExtension::ANGLE_shader_pixel_local_storage] = EBhUndefined;
+ }
+ if (resources.ANGLE_texture_multisample)
+ {
+ extBehavior[TExtension::ANGLE_texture_multisample] = EBhUndefined;
+ }
+ if (resources.ANGLE_multi_draw)
+ {
+ extBehavior[TExtension::ANGLE_multi_draw] = EBhUndefined;
+ }
+ if (resources.ANGLE_base_vertex_base_instance_shader_builtin)
+ {
+ extBehavior[TExtension::ANGLE_base_vertex_base_instance_shader_builtin] = EBhUndefined;
+ }
+ if (resources.WEBGL_video_texture)
+ {
+ extBehavior[TExtension::WEBGL_video_texture] = EBhUndefined;
+ }
+ if (resources.APPLE_clip_distance)
+ {
+ extBehavior[TExtension::APPLE_clip_distance] = EBhUndefined;
+ }
+ if (resources.OES_texture_cube_map_array)
+ {
+ extBehavior[TExtension::OES_texture_cube_map_array] = EBhUndefined;
+ }
+ if (resources.EXT_texture_cube_map_array)
+ {
+ extBehavior[TExtension::EXT_texture_cube_map_array] = EBhUndefined;
+ }
+ if (resources.EXT_shadow_samplers)
+ {
+ extBehavior[TExtension::EXT_shadow_samplers] = EBhUndefined;
+ }
+ if (resources.OES_shader_multisample_interpolation)
+ {
+ extBehavior[TExtension::OES_shader_multisample_interpolation] = EBhUndefined;
+ }
+ if (resources.OES_shader_image_atomic)
+ {
+ extBehavior[TExtension::OES_shader_image_atomic] = EBhUndefined;
+ }
+ if (resources.EXT_tessellation_shader)
+ {
+ extBehavior[TExtension::EXT_tessellation_shader] = EBhUndefined;
+ }
+ if (resources.OES_texture_buffer)
+ {
+ extBehavior[TExtension::OES_texture_buffer] = EBhUndefined;
+ }
+ if (resources.EXT_texture_buffer)
+ {
+ extBehavior[TExtension::EXT_texture_buffer] = EBhUndefined;
+ }
+ if (resources.OES_sample_variables)
+ {
+ extBehavior[TExtension::OES_sample_variables] = EBhUndefined;
+ }
+ if (resources.EXT_clip_cull_distance)
+ {
+ extBehavior[TExtension::EXT_clip_cull_distance] = EBhUndefined;
+ }
+ if (resources.ANDROID_extension_pack_es31a)
+ {
+ extBehavior[TExtension::ANDROID_extension_pack_es31a] = EBhUndefined;
+ }
+ if (resources.KHR_blend_equation_advanced)
+ {
+ extBehavior[TExtension::KHR_blend_equation_advanced] = EBhUndefined;
+ }
+}
+
+void ResetExtensionBehavior(const ShBuiltInResources &resources,
+ TExtensionBehavior &extBehavior,
+ const ShCompileOptions &compileOptions)
+{
+ for (auto &ext : extBehavior)
+ {
+ ext.second = EBhUndefined;
+ }
+ if (resources.ARB_texture_rectangle)
+ {
+ if (compileOptions.disableARBTextureRectangle)
+ {
+ // Remove ARB_texture_rectangle so it can't be enabled by extension directives.
+ extBehavior.erase(TExtension::ARB_texture_rectangle);
+ }
+ else
+ {
+ // Restore ARB_texture_rectangle in case it was removed during an earlier reset. As
+ // noted above, it doesn't follow the standard for extension directives and is
+ // enabled by default.
+ extBehavior[TExtension::ARB_texture_rectangle] = EBhEnable;
+ }
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Initialize.h b/gfx/angle/checkout/src/compiler/translator/Initialize.h
new file mode 100644
index 0000000000..727e44e277
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Initialize.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_INITIALIZE_H_
+#define COMPILER_TRANSLATOR_INITIALIZE_H_
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+void InitExtensionBehavior(const ShBuiltInResources &resources,
+ TExtensionBehavior &extensionBehavior);
+
+// Resets the behavior of the extensions listed in |extensionBehavior| to the
+// undefined state. These extensions will only be those initially supported in
+// the ShBuiltInResources object for this compiler instance. All other
+// extensions will remain unsupported.
+void ResetExtensionBehavior(const ShBuiltInResources &resources,
+ TExtensionBehavior &extensionBehavior,
+ const ShCompileOptions &compileOptions);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_INITIALIZE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/InitializeDll.cpp b/gfx/angle/checkout/src/compiler/translator/InitializeDll.cpp
new file mode 100644
index 0000000000..99a0fea19b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/InitializeDll.cpp
@@ -0,0 +1,33 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/InitializeDll.h"
+#include "compiler/translator/InitializeGlobals.h"
+
+#include "common/platform.h"
+
+#include <assert.h>
+
+namespace sh
+{
+
+bool InitProcess()
+{
+ if (!InitializePoolIndex())
+ {
+ assert(0 && "InitProcess(): Failed to initalize global pool");
+ return false;
+ }
+
+ return true;
+}
+
+void DetachProcess()
+{
+ FreePoolIndex();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/InitializeDll.h b/gfx/angle/checkout/src/compiler/translator/InitializeDll.h
new file mode 100644
index 0000000000..a75a13c2d9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/InitializeDll.h
@@ -0,0 +1,15 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+#ifndef COMPILER_TRANSLATOR_INITIALIZEDLL_H_
+#define COMPILER_TRANSLATOR_INITIALIZEDLL_H_
+
+namespace sh
+{
+bool InitProcess();
+void DetachProcess();
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_INITIALIZEDLL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/InitializeGlobals.h b/gfx/angle/checkout/src/compiler/translator/InitializeGlobals.h
new file mode 100644
index 0000000000..cf431ef4f1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/InitializeGlobals.h
@@ -0,0 +1,13 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_
+#define COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_
+
+bool InitializePoolIndex();
+void FreePoolIndex();
+
+#endif // COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp b/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp
new file mode 100644
index 0000000000..a932b534be
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp
@@ -0,0 +1,4226 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+//
+// Build the intermediate representation.
+//
+
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <vector>
+
+#include "common/mathutil.h"
+#include "common/matrix_utils.h"
+#include "common/utilities.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+const float kPi = 3.14159265358979323846f;
+const float kDegreesToRadiansMultiplier = kPi / 180.0f;
+const float kRadiansToDegreesMultiplier = 180.0f / kPi;
+
+TPrecision GetHigherPrecision(TPrecision left, TPrecision right)
+{
+ return left > right ? left : right;
+}
+
+TConstantUnion *Vectorize(const TConstantUnion &constant, size_t size)
+{
+ TConstantUnion *constUnion = new TConstantUnion[size];
+ for (size_t i = 0; i < size; ++i)
+ constUnion[i] = constant;
+
+ return constUnion;
+}
+
+void UndefinedConstantFoldingError(const TSourceLoc &loc,
+ const TFunction *function,
+ TBasicType basicType,
+ TDiagnostics *diagnostics,
+ TConstantUnion *result)
+{
+ diagnostics->warning(loc, "operation result is undefined for the values passed in",
+ function->name().data());
+
+ switch (basicType)
+ {
+ case EbtFloat:
+ result->setFConst(0.0f);
+ break;
+ case EbtInt:
+ result->setIConst(0);
+ break;
+ case EbtUInt:
+ result->setUConst(0u);
+ break;
+ case EbtBool:
+ result->setBConst(false);
+ break;
+ default:
+ break;
+ }
+}
+
+float VectorLength(const TConstantUnion *paramArray, size_t paramArraySize)
+{
+ float result = 0.0f;
+ for (size_t i = 0; i < paramArraySize; i++)
+ {
+ float f = paramArray[i].getFConst();
+ result += f * f;
+ }
+ return sqrtf(result);
+}
+
+float VectorDotProduct(const TConstantUnion *paramArray1,
+ const TConstantUnion *paramArray2,
+ size_t paramArraySize)
+{
+ float result = 0.0f;
+ for (size_t i = 0; i < paramArraySize; i++)
+ result += paramArray1[i].getFConst() * paramArray2[i].getFConst();
+ return result;
+}
+
+TIntermTyped *CreateFoldedNode(const TConstantUnion *constArray, const TIntermTyped *originalNode)
+{
+ ASSERT(constArray != nullptr);
+ // Note that we inherit whatever qualifier the folded node had. Nodes may be constant folded
+ // without being qualified as constant.
+ TIntermTyped *folded = new TIntermConstantUnion(constArray, originalNode->getType());
+ folded->setLine(originalNode->getLine());
+ return folded;
+}
+
+angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray,
+ const unsigned int rows,
+ const unsigned int cols)
+{
+ std::vector<float> elements;
+ for (size_t i = 0; i < rows * cols; i++)
+ elements.push_back(paramArray[i].getFConst());
+ // Transpose is used since the Matrix constructor expects arguments in row-major order,
+ // whereas the paramArray is in column-major order. Rows/cols parameters are also flipped below
+ // so that the created matrix will have the expected dimensions after the transpose.
+ return angle::Matrix<float>(elements, cols, rows).transpose();
+}
+
+angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray, const unsigned int size)
+{
+ std::vector<float> elements;
+ for (size_t i = 0; i < size * size; i++)
+ elements.push_back(paramArray[i].getFConst());
+ // Transpose is used since the Matrix constructor expects arguments in row-major order,
+ // whereas the paramArray is in column-major order.
+ return angle::Matrix<float>(elements, size).transpose();
+}
+
+void SetUnionArrayFromMatrix(const angle::Matrix<float> &m, TConstantUnion *resultArray)
+{
+ // Transpose is used since the input Matrix is in row-major order,
+ // whereas the actual result should be in column-major order.
+ angle::Matrix<float> result = m.transpose();
+ std::vector<float> resultElements = result.elements();
+ for (size_t i = 0; i < resultElements.size(); i++)
+ resultArray[i].setFConst(resultElements[i]);
+}
+
+bool CanFoldAggregateBuiltInOp(TOperator op)
+{
+ switch (op)
+ {
+ case EOpAtan:
+ case EOpPow:
+ case EOpMod:
+ case EOpMin:
+ case EOpMax:
+ case EOpClamp:
+ case EOpMix:
+ case EOpStep:
+ case EOpSmoothstep:
+ case EOpFma:
+ case EOpLdexp:
+ case EOpMatrixCompMult:
+ case EOpOuterProduct:
+ case EOpEqualComponentWise:
+ case EOpNotEqualComponentWise:
+ case EOpLessThanComponentWise:
+ case EOpLessThanEqualComponentWise:
+ case EOpGreaterThanComponentWise:
+ case EOpGreaterThanEqualComponentWise:
+ case EOpDistance:
+ case EOpDot:
+ case EOpCross:
+ case EOpFaceforward:
+ case EOpReflect:
+ case EOpRefract:
+ case EOpBitfieldExtract:
+ case EOpBitfieldInsert:
+ case EOpDFdx:
+ case EOpDFdy:
+ case EOpFwidth:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void PropagatePrecisionIfApplicable(TIntermTyped *node, TPrecision precision)
+{
+ if (precision == EbpUndefined || node->getPrecision() != EbpUndefined)
+ {
+ return;
+ }
+
+ if (IsPrecisionApplicableToType(node->getBasicType()))
+ {
+ node->propagatePrecision(precision);
+ }
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////
+//
+// Member functions of the nodes used for building the tree.
+//
+////////////////////////////////////////////////////////////////
+
+TIntermExpression::TIntermExpression(const TType &t) : TIntermTyped(), mType(t) {}
+
+#define REPLACE_IF_IS(node, type, original, replacement) \
+ do \
+ { \
+ if (node == original) \
+ { \
+ node = static_cast<type *>(replacement); \
+ return true; \
+ } \
+ } while (0)
+
+size_t TIntermSymbol::getChildCount() const
+{
+ return 0;
+}
+
+TIntermNode *TIntermSymbol::getChildNode(size_t index) const
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+size_t TIntermConstantUnion::getChildCount() const
+{
+ return 0;
+}
+
+TIntermNode *TIntermConstantUnion::getChildNode(size_t index) const
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+size_t TIntermLoop::getChildCount() const
+{
+ return (mInit ? 1 : 0) + (mCond ? 1 : 0) + (mExpr ? 1 : 0) + (mBody ? 1 : 0);
+}
+
+TIntermNode *TIntermLoop::getChildNode(size_t index) const
+{
+ TIntermNode *children[4];
+ unsigned int childIndex = 0;
+ if (mInit)
+ {
+ children[childIndex] = mInit;
+ ++childIndex;
+ }
+ if (mCond)
+ {
+ children[childIndex] = mCond;
+ ++childIndex;
+ }
+ if (mExpr)
+ {
+ children[childIndex] = mExpr;
+ ++childIndex;
+ }
+ if (mBody)
+ {
+ children[childIndex] = mBody;
+ ++childIndex;
+ }
+ ASSERT(index < childIndex);
+ return children[index];
+}
+
+bool TIntermLoop::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ ASSERT(original != nullptr); // This risks replacing multiple children.
+ REPLACE_IF_IS(mInit, TIntermNode, original, replacement);
+ REPLACE_IF_IS(mCond, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mBody, TIntermBlock, original, replacement);
+ return false;
+}
+
+TIntermBranch::TIntermBranch(const TIntermBranch &node)
+ : TIntermBranch(node.mFlowOp, node.mExpression ? node.mExpression->deepCopy() : nullptr)
+{}
+
+size_t TIntermBranch::getChildCount() const
+{
+ return (mExpression ? 1 : 0);
+}
+
+TIntermNode *TIntermBranch::getChildNode(size_t index) const
+{
+ ASSERT(mExpression);
+ ASSERT(index == 0);
+ return mExpression;
+}
+
+bool TIntermBranch::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mExpression, TIntermTyped, original, replacement);
+ return false;
+}
+
+size_t TIntermSwizzle::getChildCount() const
+{
+ return 1;
+}
+
+TIntermNode *TIntermSwizzle::getChildNode(size_t index) const
+{
+ ASSERT(mOperand);
+ ASSERT(index == 0);
+ return mOperand;
+}
+
+bool TIntermSwizzle::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType());
+ REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
+ return false;
+}
+
+size_t TIntermBinary::getChildCount() const
+{
+ return 2;
+}
+
+TIntermNode *TIntermBinary::getChildNode(size_t index) const
+{
+ ASSERT(index < 2);
+ if (index == 0)
+ {
+ return mLeft;
+ }
+ return mRight;
+}
+
+bool TIntermBinary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mLeft, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mRight, TIntermTyped, original, replacement);
+ return false;
+}
+
+size_t TIntermUnary::getChildCount() const
+{
+ return 1;
+}
+
+TIntermNode *TIntermUnary::getChildNode(size_t index) const
+{
+ ASSERT(mOperand);
+ ASSERT(index == 0);
+ return mOperand;
+}
+
+bool TIntermUnary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType());
+ REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
+ return false;
+}
+
+size_t TIntermGlobalQualifierDeclaration::getChildCount() const
+{
+ return 1;
+}
+
+TIntermNode *TIntermGlobalQualifierDeclaration::getChildNode(size_t index) const
+{
+ ASSERT(mSymbol);
+ ASSERT(index == 0);
+ return mSymbol;
+}
+
+bool TIntermGlobalQualifierDeclaration::replaceChildNode(TIntermNode *original,
+ TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mSymbol, TIntermSymbol, original, replacement);
+ return false;
+}
+
+size_t TIntermFunctionDefinition::getChildCount() const
+{
+ return 2;
+}
+
+TIntermNode *TIntermFunctionDefinition::getChildNode(size_t index) const
+{
+ ASSERT(index < 2);
+ if (index == 0)
+ {
+ return mPrototype;
+ }
+ return mBody;
+}
+
+bool TIntermFunctionDefinition::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mPrototype, TIntermFunctionPrototype, original, replacement);
+ REPLACE_IF_IS(mBody, TIntermBlock, original, replacement);
+ return false;
+}
+
+size_t TIntermAggregate::getChildCount() const
+{
+ return mArguments.size();
+}
+
+TIntermNode *TIntermAggregate::getChildNode(size_t index) const
+{
+ return mArguments[index];
+}
+
+bool TIntermAggregate::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ return replaceChildNodeInternal(original, replacement);
+}
+
+TIntermBlock::TIntermBlock(const TIntermBlock &node)
+{
+ for (TIntermNode *intermNode : node.mStatements)
+ {
+ mStatements.push_back(intermNode->deepCopy());
+ }
+
+ ASSERT(!node.mIsTreeRoot);
+ mIsTreeRoot = false;
+}
+
+TIntermBlock::TIntermBlock(std::initializer_list<TIntermNode *> stmts)
+{
+ for (TIntermNode *stmt : stmts)
+ {
+ appendStatement(stmt);
+ }
+}
+
+size_t TIntermBlock::getChildCount() const
+{
+ return mStatements.size();
+}
+
+TIntermNode *TIntermBlock::getChildNode(size_t index) const
+{
+ return mStatements[index];
+}
+
+bool TIntermBlock::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ return replaceChildNodeInternal(original, replacement);
+}
+
+void TIntermBlock::replaceAllChildren(const TIntermSequence &newStatements)
+{
+ mStatements.clear();
+ mStatements.insert(mStatements.begin(), newStatements.begin(), newStatements.end());
+}
+
+size_t TIntermFunctionPrototype::getChildCount() const
+{
+ return 0;
+}
+
+TIntermNode *TIntermFunctionPrototype::getChildNode(size_t index) const
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+bool TIntermFunctionPrototype::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ return false;
+}
+
+TIntermDeclaration::TIntermDeclaration(const TVariable *var, TIntermTyped *initExpr)
+{
+ if (initExpr)
+ {
+ appendDeclarator(
+ new TIntermBinary(TOperator::EOpInitialize, new TIntermSymbol(var), initExpr));
+ }
+ else
+ {
+ appendDeclarator(new TIntermSymbol(var));
+ }
+}
+
+TIntermDeclaration::TIntermDeclaration(std::initializer_list<const TVariable *> declarators)
+ : TIntermDeclaration()
+{
+ for (const TVariable *d : declarators)
+ {
+ appendDeclarator(new TIntermSymbol(d));
+ }
+}
+
+TIntermDeclaration::TIntermDeclaration(std::initializer_list<TIntermTyped *> declarators)
+ : TIntermDeclaration()
+{
+ for (TIntermTyped *d : declarators)
+ {
+ appendDeclarator(d);
+ }
+}
+
+size_t TIntermDeclaration::getChildCount() const
+{
+ return mDeclarators.size();
+}
+
+TIntermNode *TIntermDeclaration::getChildNode(size_t index) const
+{
+ return mDeclarators[index];
+}
+
+bool TIntermDeclaration::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ return replaceChildNodeInternal(original, replacement);
+}
+
+TIntermDeclaration::TIntermDeclaration(const TIntermDeclaration &node)
+{
+ for (TIntermNode *intermNode : node.mDeclarators)
+ {
+ mDeclarators.push_back(intermNode->deepCopy());
+ }
+}
+
+bool TIntermAggregateBase::replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement)
+{
+ for (size_t ii = 0; ii < getSequence()->size(); ++ii)
+ {
+ REPLACE_IF_IS((*getSequence())[ii], TIntermNode, original, replacement);
+ }
+ return false;
+}
+
+bool TIntermAggregateBase::replaceChildNodeWithMultiple(TIntermNode *original,
+ const TIntermSequence &replacements)
+{
+ for (auto it = getSequence()->begin(); it < getSequence()->end(); ++it)
+ {
+ if (*it == original)
+ {
+ it = getSequence()->erase(it);
+ getSequence()->insert(it, replacements.begin(), replacements.end());
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TIntermAggregateBase::insertChildNodes(TIntermSequence::size_type position,
+ const TIntermSequence &insertions)
+{
+ if (position > getSequence()->size())
+ {
+ return false;
+ }
+ auto it = getSequence()->begin() + position;
+ getSequence()->insert(it, insertions.begin(), insertions.end());
+ return true;
+}
+
+TIntermSymbol::TIntermSymbol(const TVariable *variable) : TIntermTyped(), mVariable(variable) {}
+
+bool TIntermSymbol::hasConstantValue() const
+{
+ return variable().getConstPointer() != nullptr;
+}
+
+const TConstantUnion *TIntermSymbol::getConstantValue() const
+{
+ return variable().getConstPointer();
+}
+
+const TSymbolUniqueId &TIntermSymbol::uniqueId() const
+{
+ return mVariable->uniqueId();
+}
+
+ImmutableString TIntermSymbol::getName() const
+{
+ return mVariable->name();
+}
+
+const TType &TIntermSymbol::getType() const
+{
+ return mVariable->getType();
+}
+
+void TIntermSymbol::propagatePrecision(TPrecision precision)
+{
+ // Every declared variable should already have a precision. Some built-ins don't have a defined
+ // precision. This is not asserted however:
+ //
+ // - A shader with no precision specified either globally or on a variable will fail with a
+ // compilation error later on.
+ // - Transformations declaring variables without precision will be caught by AST validation.
+}
+
+TIntermAggregate *TIntermAggregate::CreateFunctionCall(const TFunction &func,
+ TIntermSequence *arguments)
+{
+ return new TIntermAggregate(&func, func.getReturnType(), EOpCallFunctionInAST, arguments);
+}
+
+TIntermAggregate *TIntermAggregate::CreateRawFunctionCall(const TFunction &func,
+ TIntermSequence *arguments)
+{
+ return new TIntermAggregate(&func, func.getReturnType(), EOpCallInternalRawFunction, arguments);
+}
+
+TIntermAggregate *TIntermAggregate::CreateBuiltInFunctionCall(const TFunction &func,
+ TIntermSequence *arguments)
+{
+ // Every built-in function should have an op.
+ ASSERT(func.getBuiltInOp() != EOpNull);
+ return new TIntermAggregate(&func, func.getReturnType(), func.getBuiltInOp(), arguments);
+}
+
+TIntermAggregate *TIntermAggregate::CreateConstructor(const TType &type, TIntermSequence *arguments)
+{
+ return new TIntermAggregate(nullptr, type, EOpConstruct, arguments);
+}
+
+TIntermAggregate *TIntermAggregate::CreateConstructor(
+ const TType &type,
+ const std::initializer_list<TIntermNode *> &arguments)
+{
+ TIntermSequence argSequence(arguments);
+ return CreateConstructor(type, &argSequence);
+}
+
+TIntermAggregate::TIntermAggregate(const TFunction *func,
+ const TType &type,
+ TOperator op,
+ TIntermSequence *arguments)
+ : TIntermOperator(op, type), mUseEmulatedFunction(false), mFunction(func)
+{
+ if (arguments != nullptr)
+ {
+ mArguments.swap(*arguments);
+ }
+ ASSERT(mFunction == nullptr || mFunction->symbolType() != SymbolType::Empty);
+ setPrecisionAndQualifier();
+}
+
+void TIntermAggregate::setPrecisionAndQualifier()
+{
+ mType.setQualifier(EvqTemporary);
+ if ((!BuiltInGroup::IsBuiltIn(mOp) && !isFunctionCall()) || BuiltInGroup::IsMath(mOp))
+ {
+ if (areChildrenConstQualified())
+ {
+ mType.setQualifier(EvqConst);
+ }
+ }
+
+ propagatePrecision(derivePrecision());
+}
+
+bool TIntermAggregate::areChildrenConstQualified()
+{
+ for (TIntermNode *arg : mArguments)
+ {
+ TIntermTyped *typedArg = arg->getAsTyped();
+ if (typedArg && typedArg->getQualifier() != EvqConst)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+// Derive precision from children nodes
+TPrecision TIntermAggregate::derivePrecision() const
+{
+ if (getBasicType() == EbtBool || getBasicType() == EbtVoid || getBasicType() == EbtStruct)
+ {
+ return EbpUndefined;
+ }
+
+ // For AST function calls, take the qualifier from the declared one.
+ if (isFunctionCall())
+ {
+ return mType.getPrecision();
+ }
+
+ // Some built-ins explicitly specify their precision.
+ switch (mOp)
+ {
+ case EOpBitfieldExtract:
+ return mArguments[0]->getAsTyped()->getPrecision();
+ case EOpBitfieldInsert:
+ return GetHigherPrecision(mArguments[0]->getAsTyped()->getPrecision(),
+ mArguments[1]->getAsTyped()->getPrecision());
+ case EOpTextureSize:
+ case EOpImageSize:
+ case EOpUaddCarry:
+ case EOpUsubBorrow:
+ case EOpUmulExtended:
+ case EOpImulExtended:
+ case EOpFrexp:
+ case EOpLdexp:
+ return EbpHigh;
+ default:
+ break;
+ }
+
+ // The rest of the math operations and constructors get their precision from their arguments.
+ if (BuiltInGroup::IsMath(mOp) || mOp == EOpConstruct)
+ {
+ TPrecision precision = EbpUndefined;
+ for (TIntermNode *argument : mArguments)
+ {
+ precision = GetHigherPrecision(argument->getAsTyped()->getPrecision(), precision);
+ }
+ return precision;
+ }
+
+ // Atomic operations return highp.
+ if (BuiltInGroup::IsImageAtomic(mOp) || BuiltInGroup::IsAtomicCounter(mOp) ||
+ BuiltInGroup::IsAtomicMemory(mOp))
+ {
+ return EbpHigh;
+ }
+
+ // Texture functions return the same precision as that of the sampler (textureSize returns
+ // highp, but that's handled above). imageLoad similar takes the precision of the image. The
+ // same is true for dFd*, interpolateAt* and subpassLoad operations.
+ if (BuiltInGroup::IsTexture(mOp) || BuiltInGroup::IsImageLoad(mOp) ||
+ BuiltInGroup::IsDerivativesFS(mOp) || BuiltInGroup::IsInterpolationFS(mOp) ||
+ mOp == EOpSubpassLoad)
+ {
+ return mArguments[0]->getAsTyped()->getPrecision();
+ }
+
+ // Every possibility must be explicitly handled, except for desktop-GLSL-specific built-ins
+ // for which precision does't matter.
+ return EbpUndefined;
+}
+
+// Propagate precision to children nodes that don't already have it defined.
+void TIntermAggregate::propagatePrecision(TPrecision precision)
+{
+ mType.setPrecision(precision);
+
+ // For constructors, propagate precision to arguments.
+ if (isConstructor())
+ {
+ for (TIntermNode *arg : mArguments)
+ {
+ PropagatePrecisionIfApplicable(arg->getAsTyped(), precision);
+ }
+ return;
+ }
+
+ // For function calls, propagate precision of each parameter to its corresponding argument.
+ if (isFunctionCall())
+ {
+ for (size_t paramIndex = 0; paramIndex < mFunction->getParamCount(); ++paramIndex)
+ {
+ const TVariable *paramVariable = mFunction->getParam(paramIndex);
+ PropagatePrecisionIfApplicable(mArguments[paramIndex]->getAsTyped(),
+ paramVariable->getType().getPrecision());
+ }
+ return;
+ }
+
+ // Some built-ins explicitly specify the precision of their parameters.
+ switch (mOp)
+ {
+ case EOpUaddCarry:
+ case EOpUsubBorrow:
+ case EOpUmulExtended:
+ case EOpImulExtended:
+ PropagatePrecisionIfApplicable(mArguments[0]->getAsTyped(), EbpHigh);
+ PropagatePrecisionIfApplicable(mArguments[1]->getAsTyped(), EbpHigh);
+ break;
+ case EOpFindMSB:
+ case EOpFrexp:
+ case EOpLdexp:
+ PropagatePrecisionIfApplicable(mArguments[0]->getAsTyped(), EbpHigh);
+ break;
+ default:
+ break;
+ }
+}
+
+const char *TIntermAggregate::functionName() const
+{
+ ASSERT(!isConstructor());
+ switch (mOp)
+ {
+ case EOpCallInternalRawFunction:
+ case EOpCallFunctionInAST:
+ return mFunction->name().data();
+ default:
+ if (BuiltInGroup::IsBuiltIn(mOp))
+ {
+ return mFunction->name().data();
+ }
+ return GetOperatorString(mOp);
+ }
+}
+
+bool TIntermAggregate::hasConstantValue() const
+{
+ if (!isConstructor())
+ {
+ return false;
+ }
+ for (TIntermNode *constructorArg : mArguments)
+ {
+ if (!constructorArg->getAsTyped()->hasConstantValue())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool TIntermAggregate::isConstantNullValue() const
+{
+ if (!isConstructor())
+ {
+ return false;
+ }
+ for (TIntermNode *constructorArg : mArguments)
+ {
+ if (!constructorArg->getAsTyped()->isConstantNullValue())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+const TConstantUnion *TIntermAggregate::getConstantValue() const
+{
+ if (!hasConstantValue())
+ {
+ return nullptr;
+ }
+ ASSERT(isConstructor());
+ ASSERT(mArguments.size() > 0u);
+
+ TConstantUnion *constArray = nullptr;
+ if (isArray())
+ {
+ size_t elementSize = mArguments.front()->getAsTyped()->getType().getObjectSize();
+ constArray = new TConstantUnion[elementSize * getOutermostArraySize()];
+
+ size_t elementOffset = 0u;
+ for (TIntermNode *constructorArg : mArguments)
+ {
+ const TConstantUnion *elementConstArray =
+ constructorArg->getAsTyped()->getConstantValue();
+ ASSERT(elementConstArray);
+ size_t elementSizeBytes = sizeof(TConstantUnion) * elementSize;
+ memcpy(static_cast<void *>(&constArray[elementOffset]),
+ static_cast<const void *>(elementConstArray), elementSizeBytes);
+ elementOffset += elementSize;
+ }
+ return constArray;
+ }
+
+ size_t resultSize = getType().getObjectSize();
+ constArray = new TConstantUnion[resultSize];
+ TBasicType basicType = getBasicType();
+
+ size_t resultIndex = 0u;
+
+ if (mArguments.size() == 1u)
+ {
+ TIntermNode *argument = mArguments.front();
+ TIntermTyped *argumentTyped = argument->getAsTyped();
+ const TConstantUnion *argumentConstantValue = argumentTyped->getConstantValue();
+ // Check the special case of constructing a matrix diagonal from a single scalar,
+ // or a vector from a single scalar.
+ if (argumentTyped->getType().getObjectSize() == 1u)
+ {
+ if (isMatrix())
+ {
+ const uint8_t resultCols = getType().getCols();
+ const uint8_t resultRows = getType().getRows();
+ for (uint8_t col = 0; col < resultCols; ++col)
+ {
+ for (uint8_t row = 0; row < resultRows; ++row)
+ {
+ if (col == row)
+ {
+ constArray[resultIndex].cast(basicType, argumentConstantValue[0]);
+ }
+ else
+ {
+ constArray[resultIndex].setFConst(0.0f);
+ }
+ ++resultIndex;
+ }
+ }
+ }
+ else
+ {
+ while (resultIndex < resultSize)
+ {
+ constArray[resultIndex].cast(basicType, argumentConstantValue[0]);
+ ++resultIndex;
+ }
+ }
+ ASSERT(resultIndex == resultSize);
+ return constArray;
+ }
+ else if (isMatrix() && argumentTyped->isMatrix())
+ {
+ // The special case of constructing a matrix from a matrix.
+ const uint8_t argumentCols = argumentTyped->getType().getCols();
+ const uint8_t argumentRows = argumentTyped->getType().getRows();
+ const uint8_t resultCols = getType().getCols();
+ const uint8_t resultRows = getType().getRows();
+ for (uint8_t col = 0; col < resultCols; ++col)
+ {
+ for (uint8_t row = 0; row < resultRows; ++row)
+ {
+ if (col < argumentCols && row < argumentRows)
+ {
+ constArray[resultIndex].cast(
+ basicType, argumentConstantValue[col * argumentRows + row]);
+ }
+ else if (col == row)
+ {
+ constArray[resultIndex].setFConst(1.0f);
+ }
+ else
+ {
+ constArray[resultIndex].setFConst(0.0f);
+ }
+ ++resultIndex;
+ }
+ }
+ ASSERT(resultIndex == resultSize);
+ return constArray;
+ }
+ }
+
+ for (TIntermNode *argument : mArguments)
+ {
+ TIntermTyped *argumentTyped = argument->getAsTyped();
+ size_t argumentSize = argumentTyped->getType().getObjectSize();
+ const TConstantUnion *argumentConstantValue = argumentTyped->getConstantValue();
+ for (size_t i = 0u; i < argumentSize; ++i)
+ {
+ if (resultIndex >= resultSize)
+ break;
+ constArray[resultIndex].cast(basicType, argumentConstantValue[i]);
+ ++resultIndex;
+ }
+ }
+ ASSERT(resultIndex == resultSize);
+ return constArray;
+}
+
+bool TIntermAggregate::hasSideEffects() const
+{
+ if (getQualifier() == EvqConst)
+ {
+ return false;
+ }
+
+ // If the function itself is known to have a side effect, the expression has a side effect.
+ const bool calledFunctionHasSideEffects =
+ mFunction != nullptr && !mFunction->isKnownToNotHaveSideEffects();
+
+ if (calledFunctionHasSideEffects)
+ {
+ return true;
+ }
+
+ // Otherwise it only has a side effect if one of the arguments does.
+ for (TIntermNode *arg : mArguments)
+ {
+ if (arg->getAsTyped()->hasSideEffects())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void TIntermBlock::appendStatement(TIntermNode *statement)
+{
+ // Declaration nodes with no children can appear if it was an empty declaration or if all the
+ // declarators just added constants to the symbol table instead of generating code. We still
+ // need to add the declaration to the AST in that case because it might be relevant to the
+ // validity of switch/case.
+ if (statement != nullptr)
+ {
+ mStatements.push_back(statement);
+ }
+}
+
+void TIntermBlock::insertStatement(size_t insertPosition, TIntermNode *statement)
+{
+ ASSERT(statement != nullptr);
+ mStatements.insert(mStatements.begin() + insertPosition, statement);
+}
+
+void TIntermDeclaration::appendDeclarator(TIntermTyped *declarator)
+{
+ ASSERT(declarator != nullptr);
+ ASSERT(declarator->getAsSymbolNode() != nullptr ||
+ (declarator->getAsBinaryNode() != nullptr &&
+ declarator->getAsBinaryNode()->getOp() == EOpInitialize));
+ ASSERT(mDeclarators.empty() ||
+ declarator->getType().sameNonArrayType(mDeclarators.back()->getAsTyped()->getType()));
+ mDeclarators.push_back(declarator);
+}
+
+size_t TIntermTernary::getChildCount() const
+{
+ return 3;
+}
+
+TIntermNode *TIntermTernary::getChildNode(size_t index) const
+{
+ ASSERT(index < 3);
+ if (index == 0)
+ {
+ return mCondition;
+ }
+ if (index == 1)
+ {
+ return mTrueExpression;
+ }
+ return mFalseExpression;
+}
+
+bool TIntermTernary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mTrueExpression, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mFalseExpression, TIntermTyped, original, replacement);
+ return false;
+}
+
+size_t TIntermIfElse::getChildCount() const
+{
+ return 1 + (mTrueBlock ? 1 : 0) + (mFalseBlock ? 1 : 0);
+}
+
+TIntermNode *TIntermIfElse::getChildNode(size_t index) const
+{
+ if (index == 0)
+ {
+ return mCondition;
+ }
+ if (mTrueBlock && index == 1)
+ {
+ return mTrueBlock;
+ }
+ return mFalseBlock;
+}
+
+bool TIntermIfElse::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mTrueBlock, TIntermBlock, original, replacement);
+ REPLACE_IF_IS(mFalseBlock, TIntermBlock, original, replacement);
+ return false;
+}
+
+size_t TIntermSwitch::getChildCount() const
+{
+ return 2;
+}
+
+TIntermNode *TIntermSwitch::getChildNode(size_t index) const
+{
+ ASSERT(index < 2);
+ if (index == 0)
+ {
+ return mInit;
+ }
+ return mStatementList;
+}
+
+bool TIntermSwitch::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mInit, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mStatementList, TIntermBlock, original, replacement);
+ ASSERT(mStatementList);
+ return false;
+}
+
+TIntermCase::TIntermCase(const TIntermCase &node) : TIntermCase(node.mCondition->deepCopy()) {}
+
+size_t TIntermCase::getChildCount() const
+{
+ return (mCondition ? 1 : 0);
+}
+
+TIntermNode *TIntermCase::getChildNode(size_t index) const
+{
+ ASSERT(index == 0);
+ ASSERT(mCondition);
+ return mCondition;
+}
+
+bool TIntermCase::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
+ return false;
+}
+
+TIntermTyped::TIntermTyped() : mIsPrecise(false) {}
+TIntermTyped::TIntermTyped(const TIntermTyped &node) : TIntermTyped()
+{
+ // Copy constructor is disallowed for TIntermNode in order to disallow it for subclasses that
+ // don't explicitly allow it, so normal TIntermNode constructor is used to construct the copy.
+ // We need to manually copy any fields of TIntermNode.
+ mLine = node.mLine;
+
+ // Once deteremined, the tree is not expected to transform.
+ ASSERT(!mIsPrecise);
+}
+
+bool TIntermTyped::hasConstantValue() const
+{
+ return false;
+}
+
+bool TIntermTyped::isConstantNullValue() const
+{
+ return false;
+}
+
+const TConstantUnion *TIntermTyped::getConstantValue() const
+{
+ return nullptr;
+}
+
+TPrecision TIntermTyped::derivePrecision() const
+{
+ UNREACHABLE();
+ return EbpUndefined;
+}
+
+void TIntermTyped::propagatePrecision(TPrecision precision)
+{
+ UNREACHABLE();
+}
+
+TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node)
+ : TIntermExpression(node)
+{
+ mUnionArrayPointer = node.mUnionArrayPointer;
+}
+
+TIntermFunctionPrototype::TIntermFunctionPrototype(const TFunction *function)
+ : TIntermTyped(), mFunction(function)
+{
+ ASSERT(mFunction->symbolType() != SymbolType::Empty);
+}
+
+const TType &TIntermFunctionPrototype::getType() const
+{
+ return mFunction->getReturnType();
+}
+
+TIntermAggregate::TIntermAggregate(const TIntermAggregate &node)
+ : TIntermOperator(node),
+ mUseEmulatedFunction(node.mUseEmulatedFunction),
+ mFunction(node.mFunction)
+{
+ for (TIntermNode *arg : node.mArguments)
+ {
+ TIntermTyped *typedArg = arg->getAsTyped();
+ ASSERT(typedArg != nullptr);
+ TIntermTyped *argCopy = typedArg->deepCopy();
+ mArguments.push_back(argCopy);
+ }
+}
+
+TIntermAggregate *TIntermAggregate::shallowCopy() const
+{
+ TIntermSequence copySeq;
+ copySeq.insert(copySeq.begin(), getSequence()->begin(), getSequence()->end());
+ TIntermAggregate *copyNode = new TIntermAggregate(mFunction, mType, mOp, &copySeq);
+ copyNode->setLine(mLine);
+ return copyNode;
+}
+
+TIntermSwizzle::TIntermSwizzle(const TIntermSwizzle &node) : TIntermExpression(node)
+{
+ TIntermTyped *operandCopy = node.mOperand->deepCopy();
+ ASSERT(operandCopy != nullptr);
+ mOperand = operandCopy;
+ mSwizzleOffsets = node.mSwizzleOffsets;
+ mHasFoldedDuplicateOffsets = node.mHasFoldedDuplicateOffsets;
+}
+
+TIntermBinary::TIntermBinary(const TIntermBinary &node) : TIntermOperator(node)
+{
+ TIntermTyped *leftCopy = node.mLeft->deepCopy();
+ TIntermTyped *rightCopy = node.mRight->deepCopy();
+ ASSERT(leftCopy != nullptr && rightCopy != nullptr);
+ mLeft = leftCopy;
+ mRight = rightCopy;
+}
+
+TIntermUnary::TIntermUnary(const TIntermUnary &node)
+ : TIntermOperator(node),
+ mUseEmulatedFunction(node.mUseEmulatedFunction),
+ mFunction(node.mFunction)
+{
+ TIntermTyped *operandCopy = node.mOperand->deepCopy();
+ ASSERT(operandCopy != nullptr);
+ mOperand = operandCopy;
+}
+
+TIntermTernary::TIntermTernary(const TIntermTernary &node) : TIntermExpression(node)
+{
+ TIntermTyped *conditionCopy = node.mCondition->deepCopy();
+ TIntermTyped *trueCopy = node.mTrueExpression->deepCopy();
+ TIntermTyped *falseCopy = node.mFalseExpression->deepCopy();
+ ASSERT(conditionCopy != nullptr && trueCopy != nullptr && falseCopy != nullptr);
+ mCondition = conditionCopy;
+ mTrueExpression = trueCopy;
+ mFalseExpression = falseCopy;
+}
+
+bool TIntermOperator::isAssignment() const
+{
+ return IsAssignment(mOp);
+}
+
+bool TIntermOperator::isMultiplication() const
+{
+ switch (mOp)
+ {
+ case EOpMul:
+ case EOpMatrixTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpVectorTimesScalar:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool TIntermOperator::isConstructor() const
+{
+ return (mOp == EOpConstruct);
+}
+
+bool TIntermOperator::isFunctionCall() const
+{
+ switch (mOp)
+ {
+ case EOpCallFunctionInAST:
+ case EOpCallInternalRawFunction:
+ return true;
+ default:
+ return false;
+ }
+}
+
+TOperator TIntermBinary::GetMulOpBasedOnOperands(const TType &left, const TType &right)
+{
+ if (left.isMatrix())
+ {
+ if (right.isMatrix())
+ {
+ return EOpMatrixTimesMatrix;
+ }
+ else
+ {
+ if (right.isVector())
+ {
+ return EOpMatrixTimesVector;
+ }
+ else
+ {
+ return EOpMatrixTimesScalar;
+ }
+ }
+ }
+ else
+ {
+ if (right.isMatrix())
+ {
+ if (left.isVector())
+ {
+ return EOpVectorTimesMatrix;
+ }
+ else
+ {
+ return EOpMatrixTimesScalar;
+ }
+ }
+ else
+ {
+ // Neither operand is a matrix.
+ if (left.isVector() == right.isVector())
+ {
+ // Leave as component product.
+ return EOpMul;
+ }
+ else
+ {
+ return EOpVectorTimesScalar;
+ }
+ }
+ }
+}
+
+TOperator TIntermBinary::GetMulAssignOpBasedOnOperands(const TType &left, const TType &right)
+{
+ if (left.isMatrix())
+ {
+ if (right.isMatrix())
+ {
+ return EOpMatrixTimesMatrixAssign;
+ }
+ else
+ {
+ // right should be scalar, but this may not be validated yet.
+ return EOpMatrixTimesScalarAssign;
+ }
+ }
+ else
+ {
+ if (right.isMatrix())
+ {
+ // Left should be a vector, but this may not be validated yet.
+ return EOpVectorTimesMatrixAssign;
+ }
+ else
+ {
+ // Neither operand is a matrix.
+ if (left.isVector() == right.isVector())
+ {
+ // Leave as component product.
+ return EOpMulAssign;
+ }
+ else
+ {
+ // left should be vector and right should be scalar, but this may not be validated
+ // yet.
+ return EOpVectorTimesScalarAssign;
+ }
+ }
+ }
+}
+
+//
+// Make sure the type of a unary operator is appropriate for its
+// combination of operation and operand type.
+//
+void TIntermUnary::promote()
+{
+ if (mOp == EOpArrayLength)
+ {
+ // Special case: the qualifier of .length() doesn't depend on the operand qualifier.
+ setType(TType(EbtInt, EbpHigh, EvqConst));
+ return;
+ }
+
+ TQualifier resultQualifier = EvqTemporary;
+ if (mOperand->getQualifier() == EvqConst)
+ resultQualifier = EvqConst;
+
+ TType resultType = mOperand->getType();
+ resultType.setQualifier(resultQualifier);
+
+ // Result is an intermediate value, so make sure it's identified as such.
+ resultType.setInterfaceBlock(nullptr);
+
+ // Override type properties for special built-ins. Precision is determined later by
+ // |derivePrecision|.
+ switch (mOp)
+ {
+ case EOpFloatBitsToInt:
+ resultType.setBasicType(EbtInt);
+ break;
+ case EOpFloatBitsToUint:
+ resultType.setBasicType(EbtUInt);
+ break;
+ case EOpIntBitsToFloat:
+ case EOpUintBitsToFloat:
+ resultType.setBasicType(EbtFloat);
+ break;
+ case EOpPackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ resultType.setBasicType(EbtUInt);
+ resultType.setPrimarySize(1);
+ break;
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackUnorm2x16:
+ case EOpUnpackHalf2x16:
+ resultType.setBasicType(EbtFloat);
+ resultType.setPrimarySize(2);
+ break;
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
+ resultType.setBasicType(EbtFloat);
+ resultType.setPrimarySize(4);
+ break;
+ case EOpAny:
+ case EOpAll:
+ resultType.setBasicType(EbtBool);
+ resultType.setPrimarySize(1);
+ break;
+ case EOpLength:
+ case EOpDeterminant:
+ resultType.setBasicType(EbtFloat);
+ resultType.setPrimarySize(1);
+ resultType.setSecondarySize(1);
+ break;
+ case EOpTranspose:
+ ASSERT(resultType.getBasicType() == EbtFloat);
+ resultType.setPrimarySize(mOperand->getType().getRows());
+ resultType.setSecondarySize(mOperand->getType().getCols());
+ break;
+ case EOpIsinf:
+ case EOpIsnan:
+ resultType.setBasicType(EbtBool);
+ break;
+ case EOpBitCount:
+ case EOpFindLSB:
+ case EOpFindMSB:
+ resultType.setBasicType(EbtInt);
+ break;
+ default:
+ break;
+ }
+
+ setType(resultType);
+ propagatePrecision(derivePrecision());
+}
+
+// Derive precision from children nodes
+TPrecision TIntermUnary::derivePrecision() const
+{
+ // Unary operators generally derive their precision from their operand, except for a few
+ // built-ins where this is overriden.
+ switch (mOp)
+ {
+ case EOpArrayLength:
+ case EOpFloatBitsToInt:
+ case EOpFloatBitsToUint:
+ case EOpIntBitsToFloat:
+ case EOpUintBitsToFloat:
+ case EOpPackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackUnorm2x16:
+ case EOpBitfieldReverse:
+ return EbpHigh;
+ case EOpUnpackHalf2x16:
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
+ return EbpMedium;
+ case EOpBitCount:
+ case EOpFindLSB:
+ case EOpFindMSB:
+ return EbpLow;
+ case EOpAny:
+ case EOpAll:
+ case EOpIsinf:
+ case EOpIsnan:
+ return EbpUndefined;
+ default:
+ return mOperand->getPrecision();
+ }
+}
+
+void TIntermUnary::propagatePrecision(TPrecision precision)
+{
+ mType.setPrecision(precision);
+
+ // Generally precision of the operand and the precision of the result match. A few built-ins
+ // are exceptional.
+ switch (mOp)
+ {
+ case EOpArrayLength:
+ case EOpPackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ case EOpPackHalf2x16:
+ case EOpBitCount:
+ case EOpFindLSB:
+ case EOpFindMSB:
+ case EOpIsinf:
+ case EOpIsnan:
+ // Precision of result does not affect the operand in any way.
+ break;
+ case EOpFloatBitsToInt:
+ case EOpFloatBitsToUint:
+ case EOpIntBitsToFloat:
+ case EOpUintBitsToFloat:
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackUnorm2x16:
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
+ case EOpUnpackHalf2x16:
+ case EOpBitfieldReverse:
+ PropagatePrecisionIfApplicable(mOperand, EbpHigh);
+ break;
+ default:
+ PropagatePrecisionIfApplicable(mOperand, precision);
+ }
+}
+
+TIntermSwizzle::TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzleOffsets)
+ : TIntermExpression(TType(EbtFloat, EbpUndefined)),
+ mOperand(operand),
+ mSwizzleOffsets(swizzleOffsets),
+ mHasFoldedDuplicateOffsets(false)
+{
+ ASSERT(mOperand);
+ ASSERT(mOperand->getType().isVector());
+ ASSERT(mSwizzleOffsets.size() <= 4);
+ promote();
+}
+
+TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function)
+ : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false), mFunction(function)
+{
+ ASSERT(mOperand);
+ ASSERT(!BuiltInGroup::IsBuiltIn(op) || (function != nullptr && function->getBuiltInOp() == op));
+ promote();
+}
+
+TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right)
+ : TIntermOperator(op), mLeft(left), mRight(right)
+{
+ ASSERT(mLeft);
+ ASSERT(mRight);
+ promote();
+}
+
+TIntermBinary *TIntermBinary::CreateComma(TIntermTyped *left,
+ TIntermTyped *right,
+ int shaderVersion)
+{
+ TIntermBinary *node = new TIntermBinary(EOpComma, left, right);
+ node->getTypePointer()->setQualifier(GetCommaQualifier(shaderVersion, left, right));
+ return node;
+}
+
+TIntermGlobalQualifierDeclaration::TIntermGlobalQualifierDeclaration(TIntermSymbol *symbol,
+ bool isPrecise,
+ const TSourceLoc &line)
+ : TIntermNode(), mSymbol(symbol), mIsPrecise(isPrecise)
+{
+ ASSERT(symbol);
+ setLine(line);
+}
+
+TIntermGlobalQualifierDeclaration::TIntermGlobalQualifierDeclaration(
+ const TIntermGlobalQualifierDeclaration &node)
+ : TIntermGlobalQualifierDeclaration(static_cast<TIntermSymbol *>(node.mSymbol->deepCopy()),
+ node.mIsPrecise,
+ node.mLine)
+{}
+
+TIntermTernary::TIntermTernary(TIntermTyped *cond,
+ TIntermTyped *trueExpression,
+ TIntermTyped *falseExpression)
+ : TIntermExpression(trueExpression->getType()),
+ mCondition(cond),
+ mTrueExpression(trueExpression),
+ mFalseExpression(falseExpression)
+{
+ ASSERT(mCondition);
+ ASSERT(mTrueExpression);
+ ASSERT(mFalseExpression);
+ getTypePointer()->setQualifier(
+ TIntermTernary::DetermineQualifier(cond, trueExpression, falseExpression));
+
+ propagatePrecision(derivePrecision());
+}
+
+TIntermLoop::TIntermLoop(TLoopType type,
+ TIntermNode *init,
+ TIntermTyped *cond,
+ TIntermTyped *expr,
+ TIntermBlock *body)
+ : mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body)
+{
+ // Declaration nodes with no children can appear if all the declarators just added constants to
+ // the symbol table instead of generating code. They're no-ops so don't add them to the tree.
+ if (mInit && mInit->getAsDeclarationNode() &&
+ mInit->getAsDeclarationNode()->getSequence()->empty())
+ {
+ mInit = nullptr;
+ }
+}
+
+TIntermLoop::TIntermLoop(const TIntermLoop &node)
+ : TIntermLoop(node.mType,
+ node.mInit ? node.mInit->deepCopy() : nullptr,
+ node.mCond ? node.mCond->deepCopy() : nullptr,
+ node.mExpr ? node.mExpr->deepCopy() : nullptr,
+ node.mBody ? node.mBody->deepCopy() : nullptr)
+{}
+
+TIntermIfElse::TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB)
+ : TIntermNode(), mCondition(cond), mTrueBlock(trueB), mFalseBlock(falseB)
+{
+ ASSERT(mCondition);
+ // Prune empty false blocks so that there won't be unnecessary operations done on it.
+ if (mFalseBlock && mFalseBlock->getSequence()->empty())
+ {
+ mFalseBlock = nullptr;
+ }
+}
+
+TIntermIfElse::TIntermIfElse(const TIntermIfElse &node)
+ : TIntermIfElse(node.mCondition->deepCopy(),
+ node.mTrueBlock->deepCopy(),
+ node.mFalseBlock ? node.mFalseBlock->deepCopy() : nullptr)
+{}
+
+TIntermSwitch::TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList)
+ : TIntermNode(), mInit(init), mStatementList(statementList)
+{
+ ASSERT(mInit);
+ ASSERT(mStatementList);
+}
+
+TIntermSwitch::TIntermSwitch(const TIntermSwitch &node)
+ : TIntermSwitch(node.mInit->deepCopy(), node.mStatementList->deepCopy())
+{}
+
+void TIntermSwitch::setStatementList(TIntermBlock *statementList)
+{
+ ASSERT(statementList);
+ mStatementList = statementList;
+}
+
+// static
+TQualifier TIntermTernary::DetermineQualifier(TIntermTyped *cond,
+ TIntermTyped *trueExpression,
+ TIntermTyped *falseExpression)
+{
+ if (cond->getQualifier() == EvqConst && trueExpression->getQualifier() == EvqConst &&
+ falseExpression->getQualifier() == EvqConst)
+ {
+ return EvqConst;
+ }
+ return EvqTemporary;
+}
+
+// Derive precision from children nodes
+TPrecision TIntermTernary::derivePrecision() const
+{
+ return GetHigherPrecision(mTrueExpression->getPrecision(), mFalseExpression->getPrecision());
+}
+
+void TIntermTernary::propagatePrecision(TPrecision precision)
+{
+ mType.setPrecision(precision);
+
+ PropagatePrecisionIfApplicable(mTrueExpression, precision);
+ PropagatePrecisionIfApplicable(mFalseExpression, precision);
+}
+
+TIntermTyped *TIntermTernary::fold(TDiagnostics * /* diagnostics */)
+{
+ if (mCondition->getAsConstantUnion())
+ {
+ if (mCondition->getAsConstantUnion()->getBConst(0))
+ {
+ return mTrueExpression;
+ }
+ else
+ {
+ return mFalseExpression;
+ }
+ }
+ return this;
+}
+
+void TIntermSwizzle::promote()
+{
+ TQualifier resultQualifier = EvqTemporary;
+ if (mOperand->getQualifier() == EvqConst)
+ resultQualifier = EvqConst;
+
+ size_t numFields = mSwizzleOffsets.size();
+ setType(TType(mOperand->getBasicType(), EbpUndefined, resultQualifier,
+ static_cast<uint8_t>(numFields)));
+ propagatePrecision(derivePrecision());
+}
+
+// Derive precision from children nodes
+TPrecision TIntermSwizzle::derivePrecision() const
+{
+ return mOperand->getPrecision();
+}
+
+void TIntermSwizzle::propagatePrecision(TPrecision precision)
+{
+ mType.setPrecision(precision);
+
+ PropagatePrecisionIfApplicable(mOperand, precision);
+}
+
+bool TIntermSwizzle::hasDuplicateOffsets() const
+{
+ if (mHasFoldedDuplicateOffsets)
+ {
+ return true;
+ }
+ int offsetCount[4] = {0u, 0u, 0u, 0u};
+ for (const auto offset : mSwizzleOffsets)
+ {
+ offsetCount[offset]++;
+ if (offsetCount[offset] > 1)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void TIntermSwizzle::setHasFoldedDuplicateOffsets(bool hasFoldedDuplicateOffsets)
+{
+ mHasFoldedDuplicateOffsets = hasFoldedDuplicateOffsets;
+}
+
+bool TIntermSwizzle::offsetsMatch(int offset) const
+{
+ return mSwizzleOffsets.size() == 1 && mSwizzleOffsets[0] == offset;
+}
+
+void TIntermSwizzle::writeOffsetsAsXYZW(TInfoSinkBase *out) const
+{
+ for (const int offset : mSwizzleOffsets)
+ {
+ switch (offset)
+ {
+ case 0:
+ *out << "x";
+ break;
+ case 1:
+ *out << "y";
+ break;
+ case 2:
+ *out << "z";
+ break;
+ case 3:
+ *out << "w";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+}
+
+TQualifier TIntermBinary::GetCommaQualifier(int shaderVersion,
+ const TIntermTyped *left,
+ const TIntermTyped *right)
+{
+ // ESSL3.00 section 12.43: The result of a sequence operator is not a constant-expression.
+ if (shaderVersion >= 300 || left->getQualifier() != EvqConst ||
+ right->getQualifier() != EvqConst)
+ {
+ return EvqTemporary;
+ }
+ return EvqConst;
+}
+
+// Establishes the type of the result of the binary operation.
+void TIntermBinary::promote()
+{
+ ASSERT(!isMultiplication() ||
+ mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType()));
+
+ // Comma is handled as a special case. Note that the comma node qualifier depends on the shader
+ // version and so is not being set here.
+ if (mOp == EOpComma)
+ {
+ setType(mRight->getType());
+ return;
+ }
+
+ // Base assumption: just make the type the same as the left
+ // operand. Then only deviations from this need be coded.
+ setType(mLeft->getType());
+
+ TQualifier resultQualifier = EvqConst;
+ // Binary operations results in temporary variables unless both
+ // operands are const. If initializing a specialization constant, make the declarator also
+ // EvqSpecConst.
+ const bool isSpecConstInit = mOp == EOpInitialize && mLeft->getQualifier() == EvqSpecConst;
+ const bool isEitherNonConst =
+ mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst;
+ if (!isSpecConstInit && isEitherNonConst)
+ {
+ resultQualifier = EvqTemporary;
+ getTypePointer()->setQualifier(EvqTemporary);
+ }
+
+ // Result is an intermediate value, so make sure it's identified as such. That's not true for
+ // interface block arrays being indexed.
+ if (mOp != EOpIndexDirect && mOp != EOpIndexIndirect)
+ {
+ getTypePointer()->setInterfaceBlock(nullptr);
+ }
+
+ // Handle indexing ops.
+ switch (mOp)
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ if (mLeft->isArray())
+ {
+ mType.toArrayElementType();
+ }
+ else if (mLeft->isMatrix())
+ {
+ mType.toMatrixColumnType();
+ }
+ else if (mLeft->isVector())
+ {
+ mType.toComponentType();
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ return;
+ case EOpIndexDirectStruct:
+ {
+ const TFieldList &fields = mLeft->getType().getStruct()->fields();
+ const int fieldIndex = mRight->getAsConstantUnion()->getIConst(0);
+ setType(*fields[fieldIndex]->type());
+ getTypePointer()->setQualifier(resultQualifier);
+ return;
+ }
+ case EOpIndexDirectInterfaceBlock:
+ {
+ const TFieldList &fields = mLeft->getType().getInterfaceBlock()->fields();
+ const int fieldIndex = mRight->getAsConstantUnion()->getIConst(0);
+ setType(*fields[fieldIndex]->type());
+ getTypePointer()->setQualifier(resultQualifier);
+ return;
+ }
+ default:
+ break;
+ }
+
+ ASSERT(mLeft->isArray() == mRight->isArray());
+
+ const uint8_t nominalSize = std::max(mLeft->getNominalSize(), mRight->getNominalSize());
+
+ switch (mOp)
+ {
+ case EOpMul:
+ break;
+ case EOpMatrixTimesScalar:
+ if (mRight->isMatrix())
+ {
+ getTypePointer()->setPrimarySize(mRight->getCols());
+ getTypePointer()->setSecondarySize(mRight->getRows());
+ }
+ break;
+ case EOpMatrixTimesVector:
+ getTypePointer()->setPrimarySize(mLeft->getRows());
+ getTypePointer()->setSecondarySize(1);
+ break;
+ case EOpMatrixTimesMatrix:
+ getTypePointer()->setPrimarySize(mRight->getCols());
+ getTypePointer()->setSecondarySize(mLeft->getRows());
+ break;
+ case EOpVectorTimesScalar:
+ getTypePointer()->setPrimarySize(nominalSize);
+ break;
+ case EOpVectorTimesMatrix:
+ getTypePointer()->setPrimarySize(mRight->getCols());
+ ASSERT(getType().getSecondarySize() == 1);
+ break;
+ case EOpMulAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+ ASSERT(mOp == GetMulAssignOpBasedOnOperands(mLeft->getType(), mRight->getType()));
+ break;
+ case EOpAssign:
+ case EOpInitialize:
+ ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) &&
+ (mLeft->getSecondarySize() == mRight->getSecondarySize()));
+ break;
+ case EOpAdd:
+ case EOpSub:
+ case EOpDiv:
+ case EOpIMod:
+ case EOpBitShiftLeft:
+ case EOpBitShiftRight:
+ case EOpBitwiseAnd:
+ case EOpBitwiseXor:
+ case EOpBitwiseOr:
+ case EOpAddAssign:
+ case EOpSubAssign:
+ case EOpDivAssign:
+ case EOpIModAssign:
+ case EOpBitShiftLeftAssign:
+ case EOpBitShiftRightAssign:
+ case EOpBitwiseAndAssign:
+ case EOpBitwiseXorAssign:
+ case EOpBitwiseOrAssign:
+ {
+ ASSERT(!mLeft->isArray() && !mRight->isArray());
+ const uint8_t secondarySize =
+ std::max(mLeft->getSecondarySize(), mRight->getSecondarySize());
+ getTypePointer()->setPrimarySize(nominalSize);
+ getTypePointer()->setSecondarySize(secondarySize);
+ break;
+ }
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) &&
+ (mLeft->getSecondarySize() == mRight->getSecondarySize()));
+ setType(TType(EbtBool, EbpUndefined, resultQualifier));
+ break;
+
+ //
+ // And and Or operate on conditionals
+ //
+ case EOpLogicalAnd:
+ case EOpLogicalXor:
+ case EOpLogicalOr:
+ ASSERT(mLeft->getBasicType() == EbtBool && mRight->getBasicType() == EbtBool);
+ break;
+
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ case EOpIndexDirectInterfaceBlock:
+ case EOpIndexDirectStruct:
+ // These ops should be already fully handled.
+ UNREACHABLE();
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ propagatePrecision(derivePrecision());
+}
+
+// Derive precision from children nodes
+TPrecision TIntermBinary::derivePrecision() const
+{
+ // Assignments use the type and precision of the lvalue-expression
+ // GLSL ES spec section 5.8: Assignments
+ // "The assignment operator stores the value of rvalue-expression into the l-value and returns
+ // an r-value with the type and precision of lvalue-expression."
+ if (IsAssignment(mOp))
+ {
+ return mLeft->getPrecision();
+ }
+
+ const TPrecision higherPrecision =
+ GetHigherPrecision(mLeft->getPrecision(), mRight->getPrecision());
+
+ switch (mOp)
+ {
+ case EOpComma:
+ // Comma takes the right node's value.
+ return mRight->getPrecision();
+
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ case EOpBitShiftLeft:
+ case EOpBitShiftRight:
+ // When indexing an array, the precision of the array is preserved (which is the left
+ // node).
+ // For shift operations, the precision is derived from the expression being shifted
+ // (which is also the left node).
+ return mLeft->getPrecision();
+
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ {
+ // When selecting the field of a block, the precision is taken from the field's
+ // declaration.
+ const TFieldList &fields = mOp == EOpIndexDirectStruct
+ ? mLeft->getType().getStruct()->fields()
+ : mLeft->getType().getInterfaceBlock()->fields();
+ const int fieldIndex = mRight->getAsConstantUnion()->getIConst(0);
+ return fields[fieldIndex]->type()->getPrecision();
+ }
+
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ case EOpLogicalAnd:
+ case EOpLogicalXor:
+ case EOpLogicalOr:
+ // No precision specified on bool results.
+ return EbpUndefined;
+
+ default:
+ // All other operations are evaluated at the higher of the two operands' precisions.
+ return higherPrecision;
+ }
+}
+
+void TIntermBinary::propagatePrecision(TPrecision precision)
+{
+ getTypePointer()->setPrecision(precision);
+
+ if (mOp != EOpComma)
+ {
+ PropagatePrecisionIfApplicable(mLeft, precision);
+ }
+
+ if (mOp != EOpIndexDirect && mOp != EOpIndexIndirect && mOp != EOpIndexDirectStruct &&
+ mOp != EOpIndexDirectInterfaceBlock)
+ {
+ PropagatePrecisionIfApplicable(mRight, precision);
+ }
+
+ // For indices, always apply highp. This is purely for the purpose of making sure constant and
+ // constructor nodes are also given a precision, so if they are hoisted to a temp variable,
+ // there would be a precision to apply to that variable.
+ if (mOp == EOpIndexDirect || mOp == EOpIndexIndirect)
+ {
+ PropagatePrecisionIfApplicable(mRight, EbpHigh);
+ }
+}
+
+bool TIntermConstantUnion::hasConstantValue() const
+{
+ return true;
+}
+
+bool TIntermConstantUnion::isConstantNullValue() const
+{
+ const size_t size = mType.getObjectSize();
+ for (size_t index = 0; index < size; ++index)
+ {
+ if (!mUnionArrayPointer[index].isZero())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+const TConstantUnion *TIntermConstantUnion::getConstantValue() const
+{
+ return mUnionArrayPointer;
+}
+
+const TConstantUnion *TIntermConstantUnion::FoldIndexing(const TType &type,
+ const TConstantUnion *constArray,
+ int index)
+{
+ if (type.isArray())
+ {
+ ASSERT(index < static_cast<int>(type.getOutermostArraySize()));
+ TType arrayElementType(type);
+ arrayElementType.toArrayElementType();
+ size_t arrayElementSize = arrayElementType.getObjectSize();
+ return &constArray[arrayElementSize * index];
+ }
+ else if (type.isMatrix())
+ {
+ ASSERT(index < type.getCols());
+ const uint8_t size = type.getRows();
+ return &constArray[size * index];
+ }
+ else if (type.isVector())
+ {
+ ASSERT(index < type.getNominalSize());
+ return &constArray[index];
+ }
+ else
+ {
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+TIntermTyped *TIntermSwizzle::fold(TDiagnostics * /* diagnostics */)
+{
+ TIntermSwizzle *operandSwizzle = mOperand->getAsSwizzleNode();
+ if (operandSwizzle)
+ {
+ // We need to fold the two swizzles into one, so that repeated swizzling can't cause stack
+ // overflow in ParseContext::checkCanBeLValue().
+ bool hadDuplicateOffsets = operandSwizzle->hasDuplicateOffsets();
+ TVector<int> foldedOffsets;
+ for (int offset : mSwizzleOffsets)
+ {
+ // Offset should already be validated.
+ ASSERT(static_cast<size_t>(offset) < operandSwizzle->mSwizzleOffsets.size());
+ foldedOffsets.push_back(operandSwizzle->mSwizzleOffsets[offset]);
+ }
+ operandSwizzle->mSwizzleOffsets = foldedOffsets;
+ operandSwizzle->setType(getType());
+ operandSwizzle->setHasFoldedDuplicateOffsets(hadDuplicateOffsets);
+ return operandSwizzle;
+ }
+ TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
+ if (operandConstant == nullptr)
+ {
+ return this;
+ }
+
+ TConstantUnion *constArray = new TConstantUnion[mSwizzleOffsets.size()];
+ for (size_t i = 0; i < mSwizzleOffsets.size(); ++i)
+ {
+ constArray[i] = *TIntermConstantUnion::FoldIndexing(
+ operandConstant->getType(), operandConstant->getConstantValue(), mSwizzleOffsets.at(i));
+ }
+ return CreateFoldedNode(constArray, this);
+}
+
+TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics)
+{
+ const TConstantUnion *rightConstant = mRight->getConstantValue();
+ switch (mOp)
+ {
+ case EOpComma:
+ {
+ if (mLeft->hasSideEffects())
+ {
+ return this;
+ }
+ return mRight;
+ }
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ {
+ if (rightConstant == nullptr)
+ {
+ return this;
+ }
+ size_t index = static_cast<size_t>(rightConstant->getIConst());
+ TIntermAggregate *leftAggregate = mLeft->getAsAggregate();
+ if (leftAggregate && leftAggregate->isConstructor() && leftAggregate->isArray() &&
+ !leftAggregate->hasSideEffects())
+ {
+ ASSERT(index < leftAggregate->getSequence()->size());
+ // This transformation can't add complexity as we're eliminating the constructor
+ // entirely.
+ return leftAggregate->getSequence()->at(index)->getAsTyped();
+ }
+
+ // If the indexed value is already a constant union, we can't increase duplication of
+ // data by folding the indexing. Also fold the node in case it's generally beneficial to
+ // replace this type of node with a constant union even if that would mean duplicating
+ // data.
+ if (mLeft->getAsConstantUnion() || getType().canReplaceWithConstantUnion())
+ {
+ const TConstantUnion *constantValue = getConstantValue();
+ if (constantValue == nullptr)
+ {
+ return this;
+ }
+ return CreateFoldedNode(constantValue, this);
+ }
+ return this;
+ }
+ case EOpIndexIndirect:
+ case EOpIndexDirectInterfaceBlock:
+ case EOpInitialize:
+ // Can never be constant folded.
+ return this;
+ default:
+ {
+ if (rightConstant == nullptr)
+ {
+ return this;
+ }
+ const TConstantUnion *leftConstant = mLeft->getConstantValue();
+ if (leftConstant == nullptr)
+ {
+ return this;
+ }
+ const TConstantUnion *constArray =
+ TIntermConstantUnion::FoldBinary(mOp, leftConstant, mLeft->getType(), rightConstant,
+ mRight->getType(), diagnostics, mLeft->getLine());
+ if (!constArray)
+ {
+ return this;
+ }
+ return CreateFoldedNode(constArray, this);
+ }
+ }
+}
+
+bool TIntermBinary::hasConstantValue() const
+{
+ switch (mOp)
+ {
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ {
+ if (mLeft->hasConstantValue() && mRight->hasConstantValue())
+ {
+ return true;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return false;
+}
+
+const TConstantUnion *TIntermBinary::getConstantValue() const
+{
+ if (!hasConstantValue())
+ {
+ return nullptr;
+ }
+
+ const TConstantUnion *leftConstantValue = mLeft->getConstantValue();
+ int index = mRight->getConstantValue()->getIConst();
+ const TConstantUnion *constIndexingResult = nullptr;
+ if (mOp == EOpIndexDirect)
+ {
+ constIndexingResult =
+ TIntermConstantUnion::FoldIndexing(mLeft->getType(), leftConstantValue, index);
+ }
+ else
+ {
+ ASSERT(mOp == EOpIndexDirectStruct);
+ const TFieldList &fields = mLeft->getType().getStruct()->fields();
+
+ size_t previousFieldsSize = 0;
+ for (int i = 0; i < index; ++i)
+ {
+ previousFieldsSize += fields[i]->type()->getObjectSize();
+ }
+ constIndexingResult = leftConstantValue + previousFieldsSize;
+ }
+ return constIndexingResult;
+}
+
+const ImmutableString &TIntermBinary::getIndexStructFieldName() const
+{
+ ASSERT(mOp == EOpIndexDirectStruct);
+
+ const TType &lhsType = mLeft->getType();
+ const TStructure *structure = lhsType.getStruct();
+ const int index = mRight->getAsConstantUnion()->getIConst(0);
+
+ return structure->fields()[index]->name();
+}
+
+TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics)
+{
+ TConstantUnion *constArray = nullptr;
+
+ if (mOp == EOpArrayLength)
+ {
+ // The size of runtime-sized arrays may only be determined at runtime.
+ if (mOperand->hasSideEffects() || mOperand->getType().isUnsizedArray())
+ {
+ return this;
+ }
+ constArray = new TConstantUnion[1];
+ constArray->setIConst(mOperand->getOutermostArraySize());
+ }
+ else
+ {
+ TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
+ if (operandConstant == nullptr)
+ {
+ return this;
+ }
+
+ switch (mOp)
+ {
+ case EOpAny:
+ case EOpAll:
+ case EOpLength:
+ case EOpTranspose:
+ case EOpDeterminant:
+ case EOpInverse:
+ case EOpPackSnorm2x16:
+ case EOpUnpackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpUnpackUnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpUnpackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
+ constArray = operandConstant->foldUnaryNonComponentWise(mOp);
+ break;
+ default:
+ constArray = operandConstant->foldUnaryComponentWise(mOp, mFunction, diagnostics);
+ break;
+ }
+ }
+ if (constArray == nullptr)
+ {
+ return this;
+ }
+ return CreateFoldedNode(constArray, this);
+}
+
+TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics)
+{
+ // Make sure that all params are constant before actual constant folding.
+ for (auto *param : *getSequence())
+ {
+ if (param->getAsConstantUnion() == nullptr)
+ {
+ return this;
+ }
+ }
+ const TConstantUnion *constArray = nullptr;
+ if (isConstructor())
+ {
+ if (mType.canReplaceWithConstantUnion())
+ {
+ constArray = getConstantValue();
+ if (constArray && mType.getBasicType() == EbtUInt)
+ {
+ // Check if we converted a negative float to uint and issue a warning in that case.
+ size_t sizeRemaining = mType.getObjectSize();
+ for (TIntermNode *arg : mArguments)
+ {
+ TIntermTyped *typedArg = arg->getAsTyped();
+ if (typedArg->getBasicType() == EbtFloat)
+ {
+ const TConstantUnion *argValue = typedArg->getConstantValue();
+ size_t castSize =
+ std::min(typedArg->getType().getObjectSize(), sizeRemaining);
+ for (size_t i = 0; i < castSize; ++i)
+ {
+ if (argValue[i].getFConst() < 0.0f)
+ {
+ // ESSL 3.00.6 section 5.4.1.
+ diagnostics->warning(
+ mLine, "casting a negative float to uint is undefined",
+ mType.getBuiltInTypeNameString());
+ }
+ }
+ }
+ sizeRemaining -= typedArg->getType().getObjectSize();
+ }
+ }
+ }
+ }
+ else if (CanFoldAggregateBuiltInOp(mOp))
+ {
+ constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, diagnostics);
+ }
+ if (constArray == nullptr)
+ {
+ return this;
+ }
+ return CreateFoldedNode(constArray, this);
+}
+
+//
+// The fold functions see if an operation on a constant can be done in place,
+// without generating run-time code.
+//
+// Returns the constant value to keep using or nullptr.
+//
+const TConstantUnion *TIntermConstantUnion::FoldBinary(TOperator op,
+ const TConstantUnion *leftArray,
+ const TType &leftType,
+ const TConstantUnion *rightArray,
+ const TType &rightType,
+ TDiagnostics *diagnostics,
+ const TSourceLoc &line)
+{
+ ASSERT(leftArray && rightArray);
+
+ size_t objectSize = leftType.getObjectSize();
+
+ // for a case like float f = vec4(2, 3, 4, 5) + 1.2;
+ if (rightType.getObjectSize() == 1 && objectSize > 1)
+ {
+ rightArray = Vectorize(*rightArray, objectSize);
+ }
+ else if (rightType.getObjectSize() > 1 && objectSize == 1)
+ {
+ // for a case like float f = 1.2 + vec4(2, 3, 4, 5);
+ leftArray = Vectorize(*leftArray, rightType.getObjectSize());
+ objectSize = rightType.getObjectSize();
+ }
+
+ TConstantUnion *resultArray = nullptr;
+
+ switch (op)
+ {
+ case EOpAdd:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] =
+ TConstantUnion::add(leftArray[i], rightArray[i], diagnostics, line);
+ break;
+ case EOpSub:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] =
+ TConstantUnion::sub(leftArray[i], rightArray[i], diagnostics, line);
+ break;
+
+ case EOpMul:
+ case EOpVectorTimesScalar:
+ case EOpMatrixTimesScalar:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] =
+ TConstantUnion::mul(leftArray[i], rightArray[i], diagnostics, line);
+ break;
+
+ case EOpMatrixTimesMatrix:
+ {
+ // TODO(jmadll): This code should check for overflows.
+ ASSERT(leftType.getBasicType() == EbtFloat && rightType.getBasicType() == EbtFloat);
+
+ const uint8_t leftCols = leftType.getCols();
+ const uint8_t leftRows = leftType.getRows();
+ const uint8_t rightCols = rightType.getCols();
+ const uint8_t rightRows = rightType.getRows();
+ const uint8_t resultCols = rightCols;
+ const uint8_t resultRows = leftRows;
+
+ resultArray = new TConstantUnion[resultCols * resultRows];
+ for (uint8_t row = 0; row < resultRows; row++)
+ {
+ for (uint8_t column = 0; column < resultCols; column++)
+ {
+ resultArray[resultRows * column + row].setFConst(0.0f);
+ for (uint8_t i = 0; i < leftCols; i++)
+ {
+ resultArray[resultRows * column + row].setFConst(
+ resultArray[resultRows * column + row].getFConst() +
+ leftArray[i * leftRows + row].getFConst() *
+ rightArray[column * rightRows + i].getFConst());
+ }
+ }
+ }
+ }
+ break;
+
+ case EOpDiv:
+ case EOpIMod:
+ {
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ if (IsFloatDivision(leftType.getBasicType(), rightType.getBasicType()))
+ {
+ // Float division requested, possibly with implicit conversion
+ ASSERT(op == EOpDiv);
+ float dividend = leftArray[i].getFConst();
+ float divisor = rightArray[i].getFConst();
+
+ if (divisor == 0.0f)
+ {
+ if (dividend == 0.0f)
+ {
+ diagnostics->warning(line,
+ "Zero divided by zero during constant "
+ "folding generated NaN",
+ "/");
+ resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN());
+ }
+ else
+ {
+ diagnostics->warning(line, "Divide by zero during constant folding",
+ "/");
+ bool negativeResult = std::signbit(dividend) != std::signbit(divisor);
+ resultArray[i].setFConst(negativeResult
+ ? -std::numeric_limits<float>::infinity()
+ : std::numeric_limits<float>::infinity());
+ }
+ }
+ else if (gl::isInf(dividend) && gl::isInf(divisor))
+ {
+ diagnostics->warning(line,
+ "Infinity divided by infinity during constant "
+ "folding generated NaN",
+ "/");
+ resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN());
+ }
+ else
+ {
+ float result = dividend / divisor;
+ if (!gl::isInf(dividend) && gl::isInf(result))
+ {
+ diagnostics->warning(
+ line, "Constant folded division overflowed to infinity", "/");
+ }
+ resultArray[i].setFConst(result);
+ }
+ }
+ else
+ {
+ // Types are either both int or both uint
+ switch (leftType.getBasicType())
+ {
+ case EbtInt:
+ {
+ if (rightArray[i] == 0)
+ {
+ diagnostics->warning(
+ line, "Divide by zero error during constant folding", "/");
+ resultArray[i].setIConst(INT_MAX);
+ }
+ else
+ {
+ int lhs = leftArray[i].getIConst();
+ int divisor = rightArray[i].getIConst();
+ if (op == EOpDiv)
+ {
+ // Check for the special case where the minimum
+ // representable number is divided by -1. If left alone this
+ // leads to integer overflow in C++. ESSL 3.00.6
+ // section 4.1.3 Integers: "However, for the case where the
+ // minimum representable value is divided by -1, it is
+ // allowed to return either the minimum representable value
+ // or the maximum representable value."
+ if (lhs == -0x7fffffff - 1 && divisor == -1)
+ {
+ resultArray[i].setIConst(0x7fffffff);
+ }
+ else
+ {
+ resultArray[i].setIConst(lhs / divisor);
+ }
+ }
+ else
+ {
+ ASSERT(op == EOpIMod);
+ if (lhs < 0 || divisor < 0)
+ {
+ // ESSL 3.00.6 section 5.9: Results of modulus are
+ // undefined when either one of the operands is
+ // negative.
+ diagnostics->warning(line,
+ "Negative modulus operator operand "
+ "encountered during constant folding. "
+ "Results are undefined.",
+ "%");
+ resultArray[i].setIConst(0);
+ }
+ else
+ {
+ resultArray[i].setIConst(lhs % divisor);
+ }
+ }
+ }
+ break;
+ }
+ case EbtUInt:
+ {
+ if (rightArray[i] == 0)
+ {
+ diagnostics->warning(
+ line, "Divide by zero error during constant folding", "/");
+ resultArray[i].setUConst(UINT_MAX);
+ }
+ else
+ {
+ if (op == EOpDiv)
+ {
+ resultArray[i].setUConst(leftArray[i].getUConst() /
+ rightArray[i].getUConst());
+ }
+ else
+ {
+ ASSERT(op == EOpIMod);
+ resultArray[i].setUConst(leftArray[i].getUConst() %
+ rightArray[i].getUConst());
+ }
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ }
+ }
+ }
+ break;
+
+ case EOpMatrixTimesVector:
+ {
+ // TODO(jmadll): This code should check for overflows.
+ ASSERT(rightType.getBasicType() == EbtFloat);
+
+ const uint8_t matrixCols = leftType.getCols();
+ const uint8_t matrixRows = leftType.getRows();
+
+ resultArray = new TConstantUnion[matrixRows];
+
+ for (uint8_t matrixRow = 0; matrixRow < matrixRows; matrixRow++)
+ {
+ resultArray[matrixRow].setFConst(0.0f);
+ for (uint8_t col = 0; col < matrixCols; col++)
+ {
+ resultArray[matrixRow].setFConst(
+ resultArray[matrixRow].getFConst() +
+ leftArray[col * matrixRows + matrixRow].getFConst() *
+ rightArray[col].getFConst());
+ }
+ }
+ }
+ break;
+
+ case EOpVectorTimesMatrix:
+ {
+ // TODO(jmadll): This code should check for overflows.
+ ASSERT(leftType.getBasicType() == EbtFloat);
+
+ const uint8_t matrixCols = rightType.getCols();
+ const uint8_t matrixRows = rightType.getRows();
+
+ resultArray = new TConstantUnion[matrixCols];
+
+ for (uint8_t matrixCol = 0; matrixCol < matrixCols; matrixCol++)
+ {
+ resultArray[matrixCol].setFConst(0.0f);
+ for (uint8_t matrixRow = 0; matrixRow < matrixRows; matrixRow++)
+ {
+ resultArray[matrixCol].setFConst(
+ resultArray[matrixCol].getFConst() +
+ leftArray[matrixRow].getFConst() *
+ rightArray[matrixCol * matrixRows + matrixRow].getFConst());
+ }
+ }
+ }
+ break;
+
+ case EOpLogicalAnd:
+ {
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ resultArray[i] = leftArray[i] && rightArray[i];
+ }
+ }
+ break;
+
+ case EOpLogicalOr:
+ {
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ resultArray[i] = leftArray[i] || rightArray[i];
+ }
+ }
+ break;
+
+ case EOpLogicalXor:
+ {
+ ASSERT(leftType.getBasicType() == EbtBool);
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ resultArray[i].setBConst(leftArray[i] != rightArray[i]);
+ }
+ }
+ break;
+
+ case EOpBitwiseAnd:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] = leftArray[i] & rightArray[i];
+ break;
+ case EOpBitwiseXor:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] = leftArray[i] ^ rightArray[i];
+ break;
+ case EOpBitwiseOr:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] = leftArray[i] | rightArray[i];
+ break;
+ case EOpBitShiftLeft:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] =
+ TConstantUnion::lshift(leftArray[i], rightArray[i], diagnostics, line);
+ break;
+ case EOpBitShiftRight:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] =
+ TConstantUnion::rshift(leftArray[i], rightArray[i], diagnostics, line);
+ break;
+
+ case EOpLessThan:
+ ASSERT(objectSize == 1);
+ resultArray = new TConstantUnion[1];
+ resultArray->setBConst(*leftArray < *rightArray);
+ break;
+
+ case EOpGreaterThan:
+ ASSERT(objectSize == 1);
+ resultArray = new TConstantUnion[1];
+ resultArray->setBConst(*leftArray > *rightArray);
+ break;
+
+ case EOpLessThanEqual:
+ ASSERT(objectSize == 1);
+ resultArray = new TConstantUnion[1];
+ resultArray->setBConst(!(*leftArray > *rightArray));
+ break;
+
+ case EOpGreaterThanEqual:
+ ASSERT(objectSize == 1);
+ resultArray = new TConstantUnion[1];
+ resultArray->setBConst(!(*leftArray < *rightArray));
+ break;
+
+ case EOpEqual:
+ case EOpNotEqual:
+ {
+ resultArray = new TConstantUnion[1];
+ bool equal = true;
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ if (leftArray[i] != rightArray[i])
+ {
+ equal = false;
+ break; // break out of for loop
+ }
+ }
+ if (op == EOpEqual)
+ {
+ resultArray->setBConst(equal);
+ }
+ else
+ {
+ resultArray->setBConst(!equal);
+ }
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ return resultArray;
+}
+
+// The fold functions do operations on a constant at GLSL compile time, without generating run-time
+// code. Returns the constant value to keep using. Nullptr should not be returned.
+TConstantUnion *TIntermConstantUnion::foldUnaryNonComponentWise(TOperator op)
+{
+ // Do operations where the return type may have a different number of components compared to the
+ // operand type.
+
+ const TConstantUnion *operandArray = getConstantValue();
+ ASSERT(operandArray);
+
+ size_t objectSize = getType().getObjectSize();
+ TConstantUnion *resultArray = nullptr;
+ switch (op)
+ {
+ case EOpAny:
+ ASSERT(getType().getBasicType() == EbtBool);
+ resultArray = new TConstantUnion();
+ resultArray->setBConst(false);
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ if (operandArray[i].getBConst())
+ {
+ resultArray->setBConst(true);
+ break;
+ }
+ }
+ break;
+
+ case EOpAll:
+ ASSERT(getType().getBasicType() == EbtBool);
+ resultArray = new TConstantUnion();
+ resultArray->setBConst(true);
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ if (!operandArray[i].getBConst())
+ {
+ resultArray->setBConst(false);
+ break;
+ }
+ }
+ break;
+
+ case EOpLength:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray = new TConstantUnion();
+ resultArray->setFConst(VectorLength(operandArray, objectSize));
+ break;
+
+ case EOpTranspose:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray = new TConstantUnion[objectSize];
+ angle::Matrix<float> result =
+ GetMatrix(operandArray, getType().getRows(), getType().getCols()).transpose();
+ SetUnionArrayFromMatrix(result, resultArray);
+ break;
+ }
+
+ case EOpDeterminant:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ const uint8_t size = getType().getNominalSize();
+ ASSERT(size >= 2 && size <= 4);
+ resultArray = new TConstantUnion();
+ resultArray->setFConst(GetMatrix(operandArray, size).determinant());
+ break;
+ }
+
+ case EOpInverse:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ const uint8_t size = getType().getNominalSize();
+ ASSERT(size >= 2 && size <= 4);
+ resultArray = new TConstantUnion[objectSize];
+ angle::Matrix<float> result = GetMatrix(operandArray, size).inverse();
+ SetUnionArrayFromMatrix(result, resultArray);
+ break;
+ }
+
+ case EOpPackSnorm2x16:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ ASSERT(getType().getNominalSize() == 2);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ break;
+
+ case EOpUnpackSnorm2x16:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[2];
+ float f1, f2;
+ gl::unpackSnorm2x16(operandArray[0].getUConst(), &f1, &f2);
+ resultArray[0].setFConst(f1);
+ resultArray[1].setFConst(f2);
+ break;
+ }
+
+ case EOpPackUnorm2x16:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ ASSERT(getType().getNominalSize() == 2);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ break;
+
+ case EOpUnpackUnorm2x16:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[2];
+ float f1, f2;
+ gl::unpackUnorm2x16(operandArray[0].getUConst(), &f1, &f2);
+ resultArray[0].setFConst(f1);
+ resultArray[1].setFConst(f2);
+ break;
+ }
+
+ case EOpPackHalf2x16:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ ASSERT(getType().getNominalSize() == 2);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ break;
+
+ case EOpUnpackHalf2x16:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[2];
+ float f1, f2;
+ gl::unpackHalf2x16(operandArray[0].getUConst(), &f1, &f2);
+ resultArray[0].setFConst(f1);
+ resultArray[1].setFConst(f2);
+ break;
+ }
+
+ case EOpPackUnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::PackUnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
+ operandArray[2].getFConst(), operandArray[3].getFConst()));
+ break;
+ }
+ case EOpPackSnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::PackSnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
+ operandArray[2].getFConst(), operandArray[3].getFConst()));
+ break;
+ }
+ case EOpUnpackUnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[4];
+ float f[4];
+ gl::UnpackUnorm4x8(operandArray[0].getUConst(), f);
+ for (size_t i = 0; i < 4; ++i)
+ {
+ resultArray[i].setFConst(f[i]);
+ }
+ break;
+ }
+ case EOpUnpackSnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[4];
+ float f[4];
+ gl::UnpackSnorm4x8(operandArray[0].getUConst(), f);
+ for (size_t i = 0; i < 4; ++i)
+ {
+ resultArray[i].setFConst(f[i]);
+ }
+ break;
+ }
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return resultArray;
+}
+
+TConstantUnion *TIntermConstantUnion::foldUnaryComponentWise(TOperator op,
+ const TFunction *function,
+ TDiagnostics *diagnostics)
+{
+ // Do unary operations where each component of the result is computed based on the corresponding
+ // component of the operand. Also folds normalize, though the divisor in that case takes all
+ // components into account.
+
+ const TConstantUnion *operandArray = getConstantValue();
+ ASSERT(operandArray);
+
+ size_t objectSize = getType().getObjectSize();
+
+ TConstantUnion *resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ switch (op)
+ {
+ case EOpNegative:
+ switch (getType().getBasicType())
+ {
+ case EbtFloat:
+ resultArray[i].setFConst(-operandArray[i].getFConst());
+ break;
+ case EbtInt:
+ if (operandArray[i] == std::numeric_limits<int>::min())
+ {
+ // The minimum representable integer doesn't have a positive
+ // counterpart, rather the negation overflows and in ESSL is supposed to
+ // wrap back to the minimum representable integer. Make sure that we
+ // don't actually let the negation overflow, which has undefined
+ // behavior in C++.
+ resultArray[i].setIConst(std::numeric_limits<int>::min());
+ }
+ else
+ {
+ resultArray[i].setIConst(-operandArray[i].getIConst());
+ }
+ break;
+ case EbtUInt:
+ if (operandArray[i] == 0x80000000u)
+ {
+ resultArray[i].setUConst(0x80000000u);
+ }
+ else
+ {
+ resultArray[i].setUConst(static_cast<unsigned int>(
+ -static_cast<int>(operandArray[i].getUConst())));
+ }
+ break;
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ break;
+
+ case EOpPositive:
+ switch (getType().getBasicType())
+ {
+ case EbtFloat:
+ resultArray[i].setFConst(operandArray[i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setIConst(operandArray[i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setUConst(static_cast<unsigned int>(
+ static_cast<int>(operandArray[i].getUConst())));
+ break;
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ break;
+
+ case EOpLogicalNot:
+ switch (getType().getBasicType())
+ {
+ case EbtBool:
+ resultArray[i].setBConst(!operandArray[i].getBConst());
+ break;
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ break;
+
+ case EOpBitwiseNot:
+ switch (getType().getBasicType())
+ {
+ case EbtInt:
+ resultArray[i].setIConst(~operandArray[i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setUConst(~operandArray[i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ break;
+
+ case EOpRadians:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setFConst(kDegreesToRadiansMultiplier * operandArray[i].getFConst());
+ break;
+
+ case EOpDegrees:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setFConst(kRadiansToDegreesMultiplier * operandArray[i].getFConst());
+ break;
+
+ case EOpSin:
+ foldFloatTypeUnary(operandArray[i], &sinf, &resultArray[i]);
+ break;
+
+ case EOpCos:
+ foldFloatTypeUnary(operandArray[i], &cosf, &resultArray[i]);
+ break;
+
+ case EOpTan:
+ foldFloatTypeUnary(operandArray[i], &tanf, &resultArray[i]);
+ break;
+
+ case EOpAsin:
+ // For asin(x), results are undefined if |x| > 1, we are choosing to set result to
+ // 0.
+ if (fabsf(operandArray[i].getFConst()) > 1.0f)
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ foldFloatTypeUnary(operandArray[i], &asinf, &resultArray[i]);
+ break;
+
+ case EOpAcos:
+ // For acos(x), results are undefined if |x| > 1, we are choosing to set result to
+ // 0.
+ if (fabsf(operandArray[i].getFConst()) > 1.0f)
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ foldFloatTypeUnary(operandArray[i], &acosf, &resultArray[i]);
+ break;
+
+ case EOpAtan:
+ foldFloatTypeUnary(operandArray[i], &atanf, &resultArray[i]);
+ break;
+
+ case EOpSinh:
+ foldFloatTypeUnary(operandArray[i], &sinhf, &resultArray[i]);
+ break;
+
+ case EOpCosh:
+ foldFloatTypeUnary(operandArray[i], &coshf, &resultArray[i]);
+ break;
+
+ case EOpTanh:
+ foldFloatTypeUnary(operandArray[i], &tanhf, &resultArray[i]);
+ break;
+
+ case EOpAsinh:
+ foldFloatTypeUnary(operandArray[i], &asinhf, &resultArray[i]);
+ break;
+
+ case EOpAcosh:
+ // For acosh(x), results are undefined if x < 1, we are choosing to set result to 0.
+ if (operandArray[i].getFConst() < 1.0f)
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ foldFloatTypeUnary(operandArray[i], &acoshf, &resultArray[i]);
+ break;
+
+ case EOpAtanh:
+ // For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to
+ // 0.
+ if (fabsf(operandArray[i].getFConst()) >= 1.0f)
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ foldFloatTypeUnary(operandArray[i], &atanhf, &resultArray[i]);
+ break;
+
+ case EOpAbs:
+ switch (getType().getBasicType())
+ {
+ case EbtFloat:
+ resultArray[i].setFConst(fabsf(operandArray[i].getFConst()));
+ break;
+ case EbtInt:
+ resultArray[i].setIConst(abs(operandArray[i].getIConst()));
+ break;
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ break;
+
+ case EOpSign:
+ switch (getType().getBasicType())
+ {
+ case EbtFloat:
+ {
+ float fConst = operandArray[i].getFConst();
+ float fResult = 0.0f;
+ if (fConst > 0.0f)
+ fResult = 1.0f;
+ else if (fConst < 0.0f)
+ fResult = -1.0f;
+ resultArray[i].setFConst(fResult);
+ break;
+ }
+ case EbtInt:
+ {
+ int iConst = operandArray[i].getIConst();
+ int iResult = 0;
+ if (iConst > 0)
+ iResult = 1;
+ else if (iConst < 0)
+ iResult = -1;
+ resultArray[i].setIConst(iResult);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ break;
+
+ case EOpFloor:
+ foldFloatTypeUnary(operandArray[i], &floorf, &resultArray[i]);
+ break;
+
+ case EOpTrunc:
+ foldFloatTypeUnary(operandArray[i], &truncf, &resultArray[i]);
+ break;
+
+ case EOpRound:
+ foldFloatTypeUnary(operandArray[i], &roundf, &resultArray[i]);
+ break;
+
+ case EOpRoundEven:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ float x = operandArray[i].getFConst();
+ float result;
+ float fractPart = modff(x, &result);
+ if (fabsf(fractPart) == 0.5f)
+ result = 2.0f * roundf(x / 2.0f);
+ else
+ result = roundf(x);
+ resultArray[i].setFConst(result);
+ break;
+ }
+
+ case EOpCeil:
+ foldFloatTypeUnary(operandArray[i], &ceilf, &resultArray[i]);
+ break;
+
+ case EOpFract:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ float x = operandArray[i].getFConst();
+ resultArray[i].setFConst(x - floorf(x));
+ break;
+ }
+
+ case EOpIsnan:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setBConst(gl::isNaN(operandArray[0].getFConst()));
+ break;
+
+ case EOpIsinf:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setBConst(gl::isInf(operandArray[0].getFConst()));
+ break;
+
+ case EOpFloatBitsToInt:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setIConst(gl::bitCast<int32_t>(operandArray[0].getFConst()));
+ break;
+
+ case EOpFloatBitsToUint:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setUConst(gl::bitCast<uint32_t>(operandArray[0].getFConst()));
+ break;
+
+ case EOpIntBitsToFloat:
+ ASSERT(getType().getBasicType() == EbtInt);
+ resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getIConst()));
+ break;
+
+ case EOpUintBitsToFloat:
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getUConst()));
+ break;
+
+ case EOpExp:
+ foldFloatTypeUnary(operandArray[i], &expf, &resultArray[i]);
+ break;
+
+ case EOpLog:
+ // For log(x), results are undefined if x <= 0, we are choosing to set result to 0.
+ if (operandArray[i].getFConst() <= 0.0f)
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]);
+ break;
+
+ case EOpExp2:
+ foldFloatTypeUnary(operandArray[i], &exp2f, &resultArray[i]);
+ break;
+
+ case EOpLog2:
+ // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0.
+ // And log2f is not available on some plarforms like old android, so just using
+ // log(x)/log(2) here.
+ if (operandArray[i].getFConst() <= 0.0f)
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ {
+ foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]);
+ resultArray[i].setFConst(resultArray[i].getFConst() / logf(2.0f));
+ }
+ break;
+
+ case EOpSqrt:
+ // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0.
+ if (operandArray[i].getFConst() < 0.0f)
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]);
+ break;
+
+ case EOpInversesqrt:
+ // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(),
+ // so getting the square root first using builtin function sqrt() and then taking
+ // its inverse.
+ // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set
+ // result to 0.
+ if (operandArray[i].getFConst() <= 0.0f)
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ {
+ foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]);
+ resultArray[i].setFConst(1.0f / resultArray[i].getFConst());
+ }
+ break;
+
+ case EOpNotComponentWise:
+ ASSERT(getType().getBasicType() == EbtBool);
+ resultArray[i].setBConst(!operandArray[i].getBConst());
+ break;
+
+ case EOpNormalize:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ float x = operandArray[i].getFConst();
+ float length = VectorLength(operandArray, objectSize);
+ if (length != 0.0f)
+ resultArray[i].setFConst(x / length);
+ else
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ break;
+ }
+ case EOpBitfieldReverse:
+ {
+ uint32_t value;
+ if (getType().getBasicType() == EbtInt)
+ {
+ value = static_cast<uint32_t>(operandArray[i].getIConst());
+ }
+ else
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ value = operandArray[i].getUConst();
+ }
+ uint32_t result = gl::BitfieldReverse(value);
+ if (getType().getBasicType() == EbtInt)
+ {
+ resultArray[i].setIConst(static_cast<int32_t>(result));
+ }
+ else
+ {
+ resultArray[i].setUConst(result);
+ }
+ break;
+ }
+ case EOpBitCount:
+ {
+ uint32_t value;
+ if (getType().getBasicType() == EbtInt)
+ {
+ value = static_cast<uint32_t>(operandArray[i].getIConst());
+ }
+ else
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ value = operandArray[i].getUConst();
+ }
+ int result = gl::BitCount(value);
+ resultArray[i].setIConst(result);
+ break;
+ }
+ case EOpFindLSB:
+ {
+ uint32_t value;
+ if (getType().getBasicType() == EbtInt)
+ {
+ value = static_cast<uint32_t>(operandArray[i].getIConst());
+ }
+ else
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ value = operandArray[i].getUConst();
+ }
+ resultArray[i].setIConst(gl::FindLSB(value));
+ break;
+ }
+ case EOpFindMSB:
+ {
+ uint32_t value;
+ if (getType().getBasicType() == EbtInt)
+ {
+ int intValue = operandArray[i].getIConst();
+ value = static_cast<uint32_t>(intValue);
+ if (intValue < 0)
+ {
+ // Look for zero instead of one in value. This also handles the intValue ==
+ // -1 special case, where the return value needs to be -1.
+ value = ~value;
+ }
+ }
+ else
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ value = operandArray[i].getUConst();
+ }
+ resultArray[i].setIConst(gl::FindMSB(value));
+ break;
+ }
+
+ default:
+ return nullptr;
+ }
+ }
+
+ return resultArray;
+}
+
+void TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion &parameter,
+ FloatTypeUnaryFunc builtinFunc,
+ TConstantUnion *result) const
+{
+ ASSERT(builtinFunc);
+
+ ASSERT(getType().getBasicType() == EbtFloat);
+ result->setFConst(builtinFunc(parameter.getFConst()));
+}
+
+void TIntermConstantUnion::propagatePrecision(TPrecision precision)
+{
+ mType.setPrecision(precision);
+}
+
+// static
+TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate,
+ TDiagnostics *diagnostics)
+{
+ const TOperator op = aggregate->getOp();
+ const TFunction *function = aggregate->getFunction();
+ TIntermSequence *arguments = aggregate->getSequence();
+ unsigned int argsCount = static_cast<unsigned int>(arguments->size());
+ std::vector<const TConstantUnion *> unionArrays(argsCount);
+ std::vector<size_t> objectSizes(argsCount);
+ size_t maxObjectSize = 0;
+ TBasicType basicType = EbtVoid;
+ TSourceLoc loc;
+ for (unsigned int i = 0; i < argsCount; i++)
+ {
+ TIntermConstantUnion *argConstant = (*arguments)[i]->getAsConstantUnion();
+ ASSERT(argConstant != nullptr); // Should be checked already.
+
+ if (i == 0)
+ {
+ basicType = argConstant->getType().getBasicType();
+ loc = argConstant->getLine();
+ }
+ unionArrays[i] = argConstant->getConstantValue();
+ objectSizes[i] = argConstant->getType().getObjectSize();
+ if (objectSizes[i] > maxObjectSize)
+ maxObjectSize = objectSizes[i];
+ }
+
+ if (!(*arguments)[0]->getAsTyped()->isMatrix() && aggregate->getOp() != EOpOuterProduct)
+ {
+ for (unsigned int i = 0; i < argsCount; i++)
+ if (objectSizes[i] != maxObjectSize)
+ unionArrays[i] = Vectorize(*unionArrays[i], maxObjectSize);
+ }
+
+ TConstantUnion *resultArray = nullptr;
+
+ switch (op)
+ {
+ case EOpAtan:
+ {
+ ASSERT(basicType == EbtFloat);
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float y = unionArrays[0][i].getFConst();
+ float x = unionArrays[1][i].getFConst();
+ // Results are undefined if x and y are both 0.
+ if (x == 0.0f && y == 0.0f)
+ UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
+ &resultArray[i]);
+ else
+ resultArray[i].setFConst(atan2f(y, x));
+ }
+ break;
+ }
+
+ case EOpPow:
+ {
+ ASSERT(basicType == EbtFloat);
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float x = unionArrays[0][i].getFConst();
+ float y = unionArrays[1][i].getFConst();
+ // Results are undefined if x < 0.
+ // Results are undefined if x = 0 and y <= 0.
+ if (x < 0.0f)
+ UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
+ &resultArray[i]);
+ else if (x == 0.0f && y <= 0.0f)
+ UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
+ &resultArray[i]);
+ else
+ resultArray[i].setFConst(powf(x, y));
+ }
+ break;
+ }
+
+ case EOpMod:
+ {
+ ASSERT(basicType == EbtFloat);
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float x = unionArrays[0][i].getFConst();
+ float y = unionArrays[1][i].getFConst();
+ resultArray[i].setFConst(x - y * floorf(x / y));
+ }
+ break;
+ }
+
+ case EOpMin:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ resultArray[i].setFConst(
+ std::min(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst()));
+ break;
+ case EbtInt:
+ resultArray[i].setIConst(
+ std::min(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst()));
+ break;
+ case EbtUInt:
+ resultArray[i].setUConst(
+ std::min(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst()));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ }
+
+ case EOpMax:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ resultArray[i].setFConst(
+ std::max(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst()));
+ break;
+ case EbtInt:
+ resultArray[i].setIConst(
+ std::max(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst()));
+ break;
+ case EbtUInt:
+ resultArray[i].setUConst(
+ std::max(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst()));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ }
+
+ case EOpStep:
+ {
+ ASSERT(basicType == EbtFloat);
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ resultArray[i].setFConst(
+ unionArrays[1][i].getFConst() < unionArrays[0][i].getFConst() ? 0.0f : 1.0f);
+ break;
+ }
+
+ case EOpLessThanComponentWise:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() <
+ unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() <
+ unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() <
+ unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ }
+
+ case EOpLessThanEqualComponentWise:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() <=
+ unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() <=
+ unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() <=
+ unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ }
+
+ case EOpGreaterThanComponentWise:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() >
+ unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() >
+ unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() >
+ unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ }
+ case EOpGreaterThanEqualComponentWise:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() >=
+ unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() >=
+ unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() >=
+ unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ }
+ break;
+
+ case EOpEqualComponentWise:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() ==
+ unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() ==
+ unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() ==
+ unionArrays[1][i].getUConst());
+ break;
+ case EbtBool:
+ resultArray[i].setBConst(unionArrays[0][i].getBConst() ==
+ unionArrays[1][i].getBConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ }
+
+ case EOpNotEqualComponentWise:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() !=
+ unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() !=
+ unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() !=
+ unionArrays[1][i].getUConst());
+ break;
+ case EbtBool:
+ resultArray[i].setBConst(unionArrays[0][i].getBConst() !=
+ unionArrays[1][i].getBConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ }
+
+ case EOpDistance:
+ {
+ ASSERT(basicType == EbtFloat);
+ TConstantUnion *distanceArray = new TConstantUnion[maxObjectSize];
+ resultArray = new TConstantUnion();
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float x = unionArrays[0][i].getFConst();
+ float y = unionArrays[1][i].getFConst();
+ distanceArray[i].setFConst(x - y);
+ }
+ resultArray->setFConst(VectorLength(distanceArray, maxObjectSize));
+ break;
+ }
+
+ case EOpDot:
+ ASSERT(basicType == EbtFloat);
+ resultArray = new TConstantUnion();
+ resultArray->setFConst(VectorDotProduct(unionArrays[0], unionArrays[1], maxObjectSize));
+ break;
+
+ case EOpCross:
+ {
+ ASSERT(basicType == EbtFloat && maxObjectSize == 3);
+ resultArray = new TConstantUnion[maxObjectSize];
+ float x0 = unionArrays[0][0].getFConst();
+ float x1 = unionArrays[0][1].getFConst();
+ float x2 = unionArrays[0][2].getFConst();
+ float y0 = unionArrays[1][0].getFConst();
+ float y1 = unionArrays[1][1].getFConst();
+ float y2 = unionArrays[1][2].getFConst();
+ resultArray[0].setFConst(x1 * y2 - y1 * x2);
+ resultArray[1].setFConst(x2 * y0 - y2 * x0);
+ resultArray[2].setFConst(x0 * y1 - y0 * x1);
+ break;
+ }
+
+ case EOpReflect:
+ {
+ ASSERT(basicType == EbtFloat);
+ // genType reflect (genType I, genType N) :
+ // For the incident vector I and surface orientation N, returns the reflection
+ // direction:
+ // I - 2 * dot(N, I) * N.
+ resultArray = new TConstantUnion[maxObjectSize];
+ float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize);
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float result = unionArrays[0][i].getFConst() -
+ 2.0f * dotProduct * unionArrays[1][i].getFConst();
+ resultArray[i].setFConst(result);
+ }
+ break;
+ }
+
+ case EOpMatrixCompMult:
+ {
+ ASSERT(basicType == EbtFloat && (*arguments)[0]->getAsTyped()->isMatrix() &&
+ (*arguments)[1]->getAsTyped()->isMatrix());
+ // Perform component-wise matrix multiplication.
+ resultArray = new TConstantUnion[maxObjectSize];
+ const uint8_t rows = (*arguments)[0]->getAsTyped()->getRows();
+ const uint8_t cols = (*arguments)[0]->getAsTyped()->getCols();
+ angle::Matrix<float> lhs = GetMatrix(unionArrays[0], rows, cols);
+ angle::Matrix<float> rhs = GetMatrix(unionArrays[1], rows, cols);
+ angle::Matrix<float> result = lhs.compMult(rhs);
+ SetUnionArrayFromMatrix(result, resultArray);
+ break;
+ }
+
+ case EOpOuterProduct:
+ {
+ ASSERT(basicType == EbtFloat);
+ size_t numRows = (*arguments)[0]->getAsTyped()->getType().getObjectSize();
+ size_t numCols = (*arguments)[1]->getAsTyped()->getType().getObjectSize();
+ resultArray = new TConstantUnion[numRows * numCols];
+ angle::Matrix<float> result =
+ GetMatrix(unionArrays[0], static_cast<int>(numRows), 1)
+ .outerProduct(GetMatrix(unionArrays[1], 1, static_cast<int>(numCols)));
+ SetUnionArrayFromMatrix(result, resultArray);
+ break;
+ }
+
+ case EOpClamp:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ {
+ float x = unionArrays[0][i].getFConst();
+ float min = unionArrays[1][i].getFConst();
+ float max = unionArrays[2][i].getFConst();
+ // Results are undefined if min > max.
+ if (min > max)
+ UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
+ &resultArray[i]);
+ else
+ resultArray[i].setFConst(gl::clamp(x, min, max));
+ break;
+ }
+
+ case EbtInt:
+ {
+ int x = unionArrays[0][i].getIConst();
+ int min = unionArrays[1][i].getIConst();
+ int max = unionArrays[2][i].getIConst();
+ // Results are undefined if min > max.
+ if (min > max)
+ UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
+ &resultArray[i]);
+ else
+ resultArray[i].setIConst(gl::clamp(x, min, max));
+ break;
+ }
+ case EbtUInt:
+ {
+ unsigned int x = unionArrays[0][i].getUConst();
+ unsigned int min = unionArrays[1][i].getUConst();
+ unsigned int max = unionArrays[2][i].getUConst();
+ // Results are undefined if min > max.
+ if (min > max)
+ UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
+ &resultArray[i]);
+ else
+ resultArray[i].setUConst(gl::clamp(x, min, max));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ }
+
+ case EOpMix:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ TBasicType type = (*arguments)[2]->getAsTyped()->getType().getBasicType();
+ if (type == EbtFloat)
+ {
+ ASSERT(basicType == EbtFloat);
+ float x = unionArrays[0][i].getFConst();
+ float y = unionArrays[1][i].getFConst();
+
+ // Returns the linear blend of x and y, i.e., x * (1 - a) + y * a.
+ float a = unionArrays[2][i].getFConst();
+ resultArray[i].setFConst(x * (1.0f - a) + y * a);
+ }
+ else // 3rd parameter is EbtBool
+ {
+ ASSERT(type == EbtBool);
+ // Selects which vector each returned component comes from.
+ // For a component of a that is false, the corresponding component of x is
+ // returned.
+ // For a component of a that is true, the corresponding component of y is
+ // returned.
+ bool a = unionArrays[2][i].getBConst();
+ switch (basicType)
+ {
+ case EbtFloat:
+ {
+ float x = unionArrays[0][i].getFConst();
+ float y = unionArrays[1][i].getFConst();
+ resultArray[i].setFConst(a ? y : x);
+ }
+ break;
+ case EbtInt:
+ {
+ int x = unionArrays[0][i].getIConst();
+ int y = unionArrays[1][i].getIConst();
+ resultArray[i].setIConst(a ? y : x);
+ }
+ break;
+ case EbtUInt:
+ {
+ unsigned int x = unionArrays[0][i].getUConst();
+ unsigned int y = unionArrays[1][i].getUConst();
+ resultArray[i].setUConst(a ? y : x);
+ }
+ break;
+ case EbtBool:
+ {
+ bool x = unionArrays[0][i].getBConst();
+ bool y = unionArrays[1][i].getBConst();
+ resultArray[i].setBConst(a ? y : x);
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ case EOpSmoothstep:
+ {
+ ASSERT(basicType == EbtFloat);
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float edge0 = unionArrays[0][i].getFConst();
+ float edge1 = unionArrays[1][i].getFConst();
+ float x = unionArrays[2][i].getFConst();
+ // Results are undefined if edge0 >= edge1.
+ if (edge0 >= edge1)
+ {
+ UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
+ &resultArray[i]);
+ }
+ else
+ {
+ // Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth
+ // Hermite interpolation between 0 and 1 when edge0 < x < edge1.
+ float t = gl::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
+ resultArray[i].setFConst(t * t * (3.0f - 2.0f * t));
+ }
+ }
+ break;
+ }
+
+ case EOpFma:
+ {
+ ASSERT(basicType == EbtFloat);
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float a = unionArrays[0][i].getFConst();
+ float b = unionArrays[1][i].getFConst();
+ float c = unionArrays[2][i].getFConst();
+
+ // Returns a * b + c.
+ resultArray[i].setFConst(a * b + c);
+ }
+ break;
+ }
+
+ case EOpLdexp:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float x = unionArrays[0][i].getFConst();
+ int exp = unionArrays[1][i].getIConst();
+ if (exp > 128)
+ {
+ UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
+ &resultArray[i]);
+ }
+ else
+ {
+ resultArray[i].setFConst(gl::Ldexp(x, exp));
+ }
+ }
+ break;
+ }
+
+ case EOpFaceforward:
+ {
+ ASSERT(basicType == EbtFloat);
+ // genType faceforward(genType N, genType I, genType Nref) :
+ // If dot(Nref, I) < 0 return N, otherwise return -N.
+ resultArray = new TConstantUnion[maxObjectSize];
+ float dotProduct = VectorDotProduct(unionArrays[2], unionArrays[1], maxObjectSize);
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ if (dotProduct < 0)
+ resultArray[i].setFConst(unionArrays[0][i].getFConst());
+ else
+ resultArray[i].setFConst(-unionArrays[0][i].getFConst());
+ }
+ break;
+ }
+
+ case EOpRefract:
+ {
+ ASSERT(basicType == EbtFloat);
+ // genType refract(genType I, genType N, float eta) :
+ // For the incident vector I and surface normal N, and the ratio of indices of
+ // refraction eta,
+ // return the refraction vector. The result is computed by
+ // k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))
+ // if (k < 0.0)
+ // return genType(0.0)
+ // else
+ // return eta * I - (eta * dot(N, I) + sqrt(k)) * N
+ resultArray = new TConstantUnion[maxObjectSize];
+ float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize);
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float eta = unionArrays[2][i].getFConst();
+ float k = 1.0f - eta * eta * (1.0f - dotProduct * dotProduct);
+ if (k < 0.0f)
+ resultArray[i].setFConst(0.0f);
+ else
+ resultArray[i].setFConst(eta * unionArrays[0][i].getFConst() -
+ (eta * dotProduct + sqrtf(k)) *
+ unionArrays[1][i].getFConst());
+ }
+ break;
+ }
+ case EOpBitfieldExtract:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; ++i)
+ {
+ int offset = unionArrays[1][0].getIConst();
+ int bits = unionArrays[2][0].getIConst();
+ if (bits == 0)
+ {
+ if (aggregate->getBasicType() == EbtInt)
+ {
+ resultArray[i].setIConst(0);
+ }
+ else
+ {
+ ASSERT(aggregate->getBasicType() == EbtUInt);
+ resultArray[i].setUConst(0);
+ }
+ }
+ else if (offset < 0 || bits < 0 || offset >= 32 || bits > 32 || offset + bits > 32)
+ {
+ UndefinedConstantFoldingError(loc, function, aggregate->getBasicType(),
+ diagnostics, &resultArray[i]);
+ }
+ else
+ {
+ // bits can be 32 here, so we need to avoid bit shift overflow.
+ uint32_t maskMsb = 1u << (bits - 1);
+ uint32_t mask = ((maskMsb - 1u) | maskMsb) << offset;
+ if (aggregate->getBasicType() == EbtInt)
+ {
+ uint32_t value = static_cast<uint32_t>(unionArrays[0][i].getIConst());
+ uint32_t resultUnsigned = (value & mask) >> offset;
+ if ((resultUnsigned & maskMsb) != 0)
+ {
+ // The most significant bits (from bits+1 to the most significant bit)
+ // should be set to 1.
+ uint32_t higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;
+ resultUnsigned |= higherBitsMask;
+ }
+ resultArray[i].setIConst(static_cast<int32_t>(resultUnsigned));
+ }
+ else
+ {
+ ASSERT(aggregate->getBasicType() == EbtUInt);
+ uint32_t value = unionArrays[0][i].getUConst();
+ resultArray[i].setUConst((value & mask) >> offset);
+ }
+ }
+ }
+ break;
+ }
+ case EOpBitfieldInsert:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; ++i)
+ {
+ int offset = unionArrays[2][0].getIConst();
+ int bits = unionArrays[3][0].getIConst();
+ if (bits == 0)
+ {
+ if (aggregate->getBasicType() == EbtInt)
+ {
+ int32_t base = unionArrays[0][i].getIConst();
+ resultArray[i].setIConst(base);
+ }
+ else
+ {
+ ASSERT(aggregate->getBasicType() == EbtUInt);
+ uint32_t base = unionArrays[0][i].getUConst();
+ resultArray[i].setUConst(base);
+ }
+ }
+ else if (offset < 0 || bits < 0 || offset >= 32 || bits > 32 || offset + bits > 32)
+ {
+ UndefinedConstantFoldingError(loc, function, aggregate->getBasicType(),
+ diagnostics, &resultArray[i]);
+ }
+ else
+ {
+ // bits can be 32 here, so we need to avoid bit shift overflow.
+ uint32_t maskMsb = 1u << (bits - 1);
+ uint32_t insertMask = ((maskMsb - 1u) | maskMsb) << offset;
+ uint32_t baseMask = ~insertMask;
+ if (aggregate->getBasicType() == EbtInt)
+ {
+ uint32_t base = static_cast<uint32_t>(unionArrays[0][i].getIConst());
+ uint32_t insert = static_cast<uint32_t>(unionArrays[1][i].getIConst());
+ uint32_t resultUnsigned =
+ (base & baseMask) | ((insert << offset) & insertMask);
+ resultArray[i].setIConst(static_cast<int32_t>(resultUnsigned));
+ }
+ else
+ {
+ ASSERT(aggregate->getBasicType() == EbtUInt);
+ uint32_t base = unionArrays[0][i].getUConst();
+ uint32_t insert = unionArrays[1][i].getUConst();
+ resultArray[i].setUConst((base & baseMask) |
+ ((insert << offset) & insertMask));
+ }
+ }
+ }
+ break;
+ }
+ case EOpDFdx:
+ case EOpDFdy:
+ case EOpFwidth:
+ ASSERT(basicType == EbtFloat);
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ // Derivatives of constant arguments should be 0.
+ resultArray[i].setFConst(0.0f);
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ return resultArray;
+}
+
+bool TIntermConstantUnion::IsFloatDivision(TBasicType t1, TBasicType t2)
+{
+ ImplicitTypeConversion conversion = GetConversion(t1, t2);
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ if (t1 == EbtFloat)
+ return true;
+ return false;
+ }
+ ASSERT(t1 == EbtFloat || t2 == EbtFloat);
+ return true;
+}
+
+// TIntermPreprocessorDirective implementation.
+TIntermPreprocessorDirective::TIntermPreprocessorDirective(PreprocessorDirective directive,
+ ImmutableString command)
+ : mDirective(directive), mCommand(std::move(command))
+{}
+
+TIntermPreprocessorDirective::TIntermPreprocessorDirective(const TIntermPreprocessorDirective &node)
+ : TIntermPreprocessorDirective(node.mDirective, node.mCommand)
+{}
+
+TIntermPreprocessorDirective::~TIntermPreprocessorDirective() = default;
+
+size_t TIntermPreprocessorDirective::getChildCount() const
+{
+ return 0;
+}
+
+TIntermNode *TIntermPreprocessorDirective::getChildNode(size_t index) const
+{
+ UNREACHABLE();
+ return nullptr;
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/IntermNode.h b/gfx/angle/checkout/src/compiler/translator/IntermNode.h
new file mode 100644
index 0000000000..81b5fcce43
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/IntermNode.h
@@ -0,0 +1,1046 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+//
+// Definition of the in-memory high-level intermediate representation
+// of shaders. This is a tree that parser creates.
+//
+// Nodes in the tree are defined as a hierarchy of classes derived from
+// TIntermNode. Each is a node in a tree. There is no preset branching factor;
+// each node can have it's own type of list of children.
+//
+
+#ifndef COMPILER_TRANSLATOR_INTERMNODE_H_
+#define COMPILER_TRANSLATOR_INTERMNODE_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+#include <algorithm>
+#include <queue>
+
+#include "common/angleutils.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/ConstantUnion.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/Operator_autogen.h"
+#include "compiler/translator/SymbolUniqueId.h"
+#include "compiler/translator/Types.h"
+#include "compiler/translator/tree_util/Visit.h"
+
+namespace sh
+{
+
+class TDiagnostics;
+
+class TIntermTraverser;
+class TIntermAggregate;
+class TIntermBlock;
+class TIntermGlobalQualifierDeclaration;
+class TIntermDeclaration;
+class TIntermFunctionPrototype;
+class TIntermFunctionDefinition;
+class TIntermSwizzle;
+class TIntermBinary;
+class TIntermUnary;
+class TIntermConstantUnion;
+class TIntermTernary;
+class TIntermIfElse;
+class TIntermSwitch;
+class TIntermCase;
+class TIntermTyped;
+class TIntermSymbol;
+class TIntermLoop;
+class TInfoSink;
+class TInfoSinkBase;
+class TIntermBranch;
+class TIntermPreprocessorDirective;
+
+class TSymbolTable;
+class TFunction;
+class TVariable;
+
+//
+// Base class for the tree nodes
+//
+class TIntermNode : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TIntermNode()
+ {
+ // TODO: Move this to TSourceLoc constructor
+ // after getting rid of TPublicType.
+ mLine.first_file = mLine.last_file = 0;
+ mLine.first_line = mLine.last_line = 0;
+ }
+ virtual ~TIntermNode() {}
+
+ const TSourceLoc &getLine() const { return mLine; }
+ void setLine(const TSourceLoc &l) { mLine = l; }
+
+ virtual void traverse(TIntermTraverser *it);
+ virtual bool visit(Visit visit, TIntermTraverser *it) = 0;
+
+ virtual TIntermTyped *getAsTyped() { return nullptr; }
+ virtual TIntermConstantUnion *getAsConstantUnion() { return nullptr; }
+ virtual TIntermFunctionDefinition *getAsFunctionDefinition() { return nullptr; }
+ virtual TIntermAggregate *getAsAggregate() { return nullptr; }
+ virtual TIntermBlock *getAsBlock() { return nullptr; }
+ virtual TIntermFunctionPrototype *getAsFunctionPrototypeNode() { return nullptr; }
+ virtual TIntermGlobalQualifierDeclaration *getAsGlobalQualifierDeclarationNode()
+ {
+ return nullptr;
+ }
+ virtual TIntermDeclaration *getAsDeclarationNode() { return nullptr; }
+ virtual TIntermSwizzle *getAsSwizzleNode() { return nullptr; }
+ virtual TIntermBinary *getAsBinaryNode() { return nullptr; }
+ virtual TIntermUnary *getAsUnaryNode() { return nullptr; }
+ virtual TIntermTernary *getAsTernaryNode() { return nullptr; }
+ virtual TIntermIfElse *getAsIfElseNode() { return nullptr; }
+ virtual TIntermSwitch *getAsSwitchNode() { return nullptr; }
+ virtual TIntermCase *getAsCaseNode() { return nullptr; }
+ virtual TIntermSymbol *getAsSymbolNode() { return nullptr; }
+ virtual TIntermLoop *getAsLoopNode() { return nullptr; }
+ virtual TIntermBranch *getAsBranchNode() { return nullptr; }
+ virtual TIntermPreprocessorDirective *getAsPreprocessorDirective() { return nullptr; }
+
+ virtual TIntermNode *deepCopy() const = 0;
+
+ virtual size_t getChildCount() const = 0;
+ virtual TIntermNode *getChildNode(size_t index) const = 0;
+ // Replace a child node. Return true if |original| is a child
+ // node and it is replaced; otherwise, return false.
+ virtual bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) = 0;
+
+ protected:
+ TSourceLoc mLine;
+};
+
+//
+// This is just to help yacc.
+//
+struct TIntermNodePair
+{
+ TIntermNode *node1;
+ TIntermNode *node2;
+};
+
+//
+// Intermediate class for nodes that have a type.
+//
+class TIntermTyped : public TIntermNode
+{
+ public:
+ TIntermTyped();
+
+ virtual TIntermTyped *deepCopy() const override = 0;
+
+ TIntermTyped *getAsTyped() override { return this; }
+
+ virtual TIntermTyped *fold(TDiagnostics *diagnostics) { return this; }
+
+ // getConstantValue() returns the constant value that this node represents, if any. It
+ // should only be used after nodes have been replaced with their folded versions returned
+ // from fold(). hasConstantValue() returns true if getConstantValue() will return a value.
+ virtual bool hasConstantValue() const;
+ virtual bool isConstantNullValue() const;
+ virtual const TConstantUnion *getConstantValue() const;
+
+ // True if executing the expression represented by this node affects state, like values of
+ // variables. False if the executing the expression only computes its return value without
+ // affecting state. May return true conservatively.
+ virtual bool hasSideEffects() const = 0;
+
+ virtual const TType &getType() const = 0;
+
+ // Derive the precision of the node based on its children's.
+ virtual TPrecision derivePrecision() const;
+ // Set precision of the current node and propagate it to any child node that doesn't have
+ // precision. This should be the case only for TIntermConstantUnion nodes as every other node
+ // would already need to have its precision specified or derived.
+ virtual void propagatePrecision(TPrecision precision);
+
+ TBasicType getBasicType() const { return getType().getBasicType(); }
+ TQualifier getQualifier() const { return getType().getQualifier(); }
+ TPrecision getPrecision() const { return getType().getPrecision(); }
+ TMemoryQualifier getMemoryQualifier() const { return getType().getMemoryQualifier(); }
+ uint8_t getCols() const { return getType().getCols(); }
+ uint8_t getRows() const { return getType().getRows(); }
+ uint8_t getNominalSize() const { return getType().getNominalSize(); }
+ uint8_t getSecondarySize() const { return getType().getSecondarySize(); }
+
+ bool isInterfaceBlock() const { return getType().isInterfaceBlock(); }
+ bool isMatrix() const { return getType().isMatrix(); }
+ bool isArray() const { return getType().isArray(); }
+ bool isVector() const { return getType().isVector(); }
+ bool isScalar() const { return getType().isScalar(); }
+ bool isScalarInt() const { return getType().isScalarInt(); }
+ const char *getBasicString() const { return getType().getBasicString(); }
+
+ unsigned int getOutermostArraySize() const { return getType().getOutermostArraySize(); }
+
+ // After every transformation is done and just before outputting the tree (i.e. when the tree
+ // nodes are no longer going to change), the tree is traversed to gather some information to be
+ // stored in the intermediate nodes:
+ //
+ // - Precise-ness, which is set for arithmetic nodes that are involved in the calculation of a
+ // value assigned to a |precise| variable.
+ void setIsPrecise() { mIsPrecise = true; }
+ bool isPrecise() const { return mIsPrecise; }
+
+ protected:
+ TIntermTyped(const TIntermTyped &node);
+
+ bool mIsPrecise;
+};
+
+//
+// Handle for, do-while, and while loops.
+//
+enum TLoopType
+{
+ ELoopFor,
+ ELoopWhile,
+ ELoopDoWhile
+};
+
+class TIntermLoop : public TIntermNode
+{
+ public:
+ TIntermLoop(TLoopType type,
+ TIntermNode *init,
+ TIntermTyped *cond,
+ TIntermTyped *expr,
+ TIntermBlock *body);
+
+ TIntermLoop *getAsLoopNode() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TLoopType getType() const { return mType; }
+ TIntermNode *getInit() { return mInit; }
+ TIntermTyped *getCondition() { return mCond; }
+ TIntermTyped *getExpression() { return mExpr; }
+ TIntermBlock *getBody() { return mBody; }
+
+ void setInit(TIntermNode *init) { mInit = init; }
+ void setCondition(TIntermTyped *condition) { mCond = condition; }
+ void setExpression(TIntermTyped *expression) { mExpr = expression; }
+ void setBody(TIntermBlock *body) { mBody = body; }
+
+ virtual TIntermLoop *deepCopy() const override { return new TIntermLoop(*this); }
+
+ protected:
+ TLoopType mType;
+ TIntermNode *mInit; // for-loop initialization
+ TIntermTyped *mCond; // loop exit condition
+ TIntermTyped *mExpr; // for-loop expression
+ TIntermBlock *mBody; // loop body
+
+ private:
+ TIntermLoop(const TIntermLoop &);
+};
+
+//
+// Handle break, continue, return, and kill.
+//
+class TIntermBranch : public TIntermNode
+{
+ public:
+ TIntermBranch(TOperator op, TIntermTyped *e) : mFlowOp(op), mExpression(e) {}
+
+ TIntermBranch *getAsBranchNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TOperator getFlowOp() { return mFlowOp; }
+ TIntermTyped *getExpression() { return mExpression; }
+
+ virtual TIntermBranch *deepCopy() const override { return new TIntermBranch(*this); }
+
+ protected:
+ TOperator mFlowOp;
+ TIntermTyped *mExpression; // zero except for "return exp;" statements
+
+ private:
+ TIntermBranch(const TIntermBranch &);
+};
+
+// Nodes that correspond to variable symbols in the source code. These may be regular variables or
+// interface block instances. In declarations that only declare a struct type but no variables, a
+// TIntermSymbol node with an empty variable is used to store the type.
+class TIntermSymbol : public TIntermTyped
+{
+ public:
+ TIntermSymbol(const TVariable *variable);
+
+ TIntermTyped *deepCopy() const override { return new TIntermSymbol(*this); }
+
+ bool hasConstantValue() const override;
+ const TConstantUnion *getConstantValue() const override;
+
+ bool hasSideEffects() const override { return false; }
+
+ const TType &getType() const override;
+
+ const TSymbolUniqueId &uniqueId() const;
+ ImmutableString getName() const;
+ const TVariable &variable() const { return *mVariable; }
+
+ TIntermSymbol *getAsSymbolNode() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }
+
+ private:
+ TIntermSymbol(const TIntermSymbol &) = default; // Note: not deleted, just private!
+ void propagatePrecision(TPrecision precision) override;
+
+ const TVariable *const mVariable; // Guaranteed to be non-null
+};
+
+// A typed expression that is not just representing a symbol table symbol.
+class TIntermExpression : public TIntermTyped
+{
+ public:
+ TIntermExpression(const TType &t);
+
+ const TType &getType() const override { return mType; }
+
+ protected:
+ TType *getTypePointer() { return &mType; }
+ void setType(const TType &t) { mType = t; }
+
+ TIntermExpression(const TIntermExpression &node) = default;
+
+ TType mType;
+};
+
+// Constant folded node.
+// Note that nodes may be constant folded and not be constant expressions with the EvqConst
+// qualifier. This happens for example when the following expression is processed:
+// "true ? 1.0 : non_constant"
+// Other nodes than TIntermConstantUnion may also be constant expressions.
+//
+class TIntermConstantUnion : public TIntermExpression
+{
+ public:
+ TIntermConstantUnion(const TConstantUnion *unionPointer, const TType &type)
+ : TIntermExpression(type), mUnionArrayPointer(unionPointer)
+ {
+ ASSERT(unionPointer);
+ }
+
+ TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); }
+
+ bool hasConstantValue() const override;
+ bool isConstantNullValue() const override;
+ const TConstantUnion *getConstantValue() const override;
+
+ bool hasSideEffects() const override { return false; }
+
+ int getIConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getIConst() : 0;
+ }
+ unsigned int getUConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getUConst() : 0;
+ }
+ float getFConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getFConst() : 0.0f;
+ }
+ bool getBConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getBConst() : false;
+ }
+ bool isZero(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].isZero() : false;
+ }
+
+ TIntermConstantUnion *getAsConstantUnion() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }
+
+ TConstantUnion *foldUnaryNonComponentWise(TOperator op);
+ TConstantUnion *foldUnaryComponentWise(TOperator op,
+ const TFunction *function,
+ TDiagnostics *diagnostics);
+
+ static const TConstantUnion *FoldBinary(TOperator op,
+ const TConstantUnion *leftArray,
+ const TType &leftType,
+ const TConstantUnion *rightArray,
+ const TType &rightType,
+ TDiagnostics *diagnostics,
+ const TSourceLoc &line);
+
+ static const TConstantUnion *FoldIndexing(const TType &type,
+ const TConstantUnion *constArray,
+ int index);
+ static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate,
+ TDiagnostics *diagnostics);
+ static bool IsFloatDivision(TBasicType t1, TBasicType t2);
+
+ protected:
+ // Same data may be shared between multiple constant unions, so it can't be modified.
+ const TConstantUnion *mUnionArrayPointer;
+
+ private:
+ typedef float (*FloatTypeUnaryFunc)(float);
+ void foldFloatTypeUnary(const TConstantUnion &parameter,
+ FloatTypeUnaryFunc builtinFunc,
+ TConstantUnion *result) const;
+ void propagatePrecision(TPrecision precision) override;
+
+ TIntermConstantUnion(const TIntermConstantUnion &node); // Note: not deleted, just private!
+};
+
+//
+// Intermediate class for node types that hold operators.
+//
+class TIntermOperator : public TIntermExpression
+{
+ public:
+ TOperator getOp() const { return mOp; }
+
+ bool isAssignment() const;
+ bool isMultiplication() const;
+ bool isConstructor() const;
+
+ // Returns true for calls mapped to EOpCall*, false for all built-ins.
+ bool isFunctionCall() const;
+
+ bool hasSideEffects() const override { return isAssignment(); }
+
+ protected:
+ TIntermOperator(TOperator op) : TIntermExpression(TType(EbtFloat, EbpUndefined)), mOp(op) {}
+ TIntermOperator(TOperator op, const TType &type) : TIntermExpression(type), mOp(op) {}
+
+ TIntermOperator(const TIntermOperator &) = default;
+
+ const TOperator mOp;
+};
+
+// Node for vector swizzles.
+class TIntermSwizzle : public TIntermExpression
+{
+ public:
+ // This constructor determines the type of the node based on the operand.
+ TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzleOffsets);
+
+ TIntermTyped *deepCopy() const override { return new TIntermSwizzle(*this); }
+
+ TIntermSwizzle *getAsSwizzleNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ bool hasSideEffects() const override { return mOperand->hasSideEffects(); }
+
+ TIntermTyped *getOperand() { return mOperand; }
+ void writeOffsetsAsXYZW(TInfoSinkBase *out) const;
+
+ const TVector<int> &getSwizzleOffsets() { return mSwizzleOffsets; }
+
+ bool hasDuplicateOffsets() const;
+ void setHasFoldedDuplicateOffsets(bool hasFoldedDuplicateOffsets);
+ bool offsetsMatch(int offset) const;
+
+ TIntermTyped *fold(TDiagnostics *diagnostics) override;
+
+ protected:
+ TIntermTyped *mOperand;
+ TVector<int> mSwizzleOffsets;
+ bool mHasFoldedDuplicateOffsets;
+
+ private:
+ void promote();
+ TPrecision derivePrecision() const override;
+ void propagatePrecision(TPrecision precision) override;
+
+ TIntermSwizzle(const TIntermSwizzle &node); // Note: not deleted, just private!
+};
+
+//
+// Nodes for all the basic binary math operators.
+//
+class TIntermBinary : public TIntermOperator
+{
+ public:
+ // This constructor determines the type of the binary node based on the operands and op.
+ TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right);
+ // Comma qualifier depends on the shader version, so use this to create comma nodes:
+ static TIntermBinary *CreateComma(TIntermTyped *left, TIntermTyped *right, int shaderVersion);
+
+ TIntermTyped *deepCopy() const override { return new TIntermBinary(*this); }
+
+ bool hasConstantValue() const override;
+ const TConstantUnion *getConstantValue() const override;
+
+ static TOperator GetMulOpBasedOnOperands(const TType &left, const TType &right);
+ static TOperator GetMulAssignOpBasedOnOperands(const TType &left, const TType &right);
+
+ TIntermBinary *getAsBinaryNode() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ bool hasSideEffects() const override
+ {
+ return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects();
+ }
+
+ TIntermTyped *getLeft() const { return mLeft; }
+ TIntermTyped *getRight() const { return mRight; }
+ TIntermTyped *fold(TDiagnostics *diagnostics) override;
+
+ // This method is only valid for EOpIndexDirectStruct. It returns the name of the field.
+ const ImmutableString &getIndexStructFieldName() const;
+
+ protected:
+ TIntermTyped *mLeft;
+ TIntermTyped *mRight;
+
+ private:
+ void promote();
+ TPrecision derivePrecision() const override;
+ void propagatePrecision(TPrecision precision) override;
+
+ static TQualifier GetCommaQualifier(int shaderVersion,
+ const TIntermTyped *left,
+ const TIntermTyped *right);
+
+ TIntermBinary(const TIntermBinary &node); // Note: not deleted, just private!
+};
+
+//
+// Nodes for unary math operators.
+//
+class TIntermUnary : public TIntermOperator
+{
+ public:
+ TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function);
+
+ TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); }
+
+ TIntermUnary *getAsUnaryNode() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ bool hasSideEffects() const override { return isAssignment() || mOperand->hasSideEffects(); }
+
+ TIntermTyped *getOperand() { return mOperand; }
+ TIntermTyped *fold(TDiagnostics *diagnostics) override;
+
+ const TFunction *getFunction() const { return mFunction; }
+
+ void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
+ bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
+
+ protected:
+ TIntermTyped *mOperand;
+
+ // If set to true, replace the built-in function call with an emulated one
+ // to work around driver bugs.
+ bool mUseEmulatedFunction;
+
+ const TFunction *const mFunction;
+
+ private:
+ void promote();
+ TPrecision derivePrecision() const override;
+ void propagatePrecision(TPrecision precision) override;
+
+ TIntermUnary(const TIntermUnary &node); // note: not deleted, just private!
+};
+
+typedef TVector<TIntermNode *> TIntermSequence;
+typedef TVector<int> TQualifierList;
+
+// Interface for node classes that have an arbitrarily sized set of children.
+class TIntermAggregateBase
+{
+ public:
+ virtual ~TIntermAggregateBase() {}
+
+ virtual TIntermSequence *getSequence() = 0;
+ virtual const TIntermSequence *getSequence() const = 0;
+
+ bool replaceChildNodeWithMultiple(TIntermNode *original, const TIntermSequence &replacements);
+ bool insertChildNodes(TIntermSequence::size_type position, const TIntermSequence &insertions);
+
+ protected:
+ TIntermAggregateBase() {}
+
+ bool replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement);
+};
+
+//
+// Nodes that operate on an arbitrary sized set of children.
+//
+class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
+{
+ public:
+ static TIntermAggregate *CreateFunctionCall(const TFunction &func, TIntermSequence *arguments);
+
+ static TIntermAggregate *CreateRawFunctionCall(const TFunction &func,
+ TIntermSequence *arguments);
+
+ // This covers all built-in function calls.
+ static TIntermAggregate *CreateBuiltInFunctionCall(const TFunction &func,
+ TIntermSequence *arguments);
+ static TIntermAggregate *CreateConstructor(const TType &type, TIntermSequence *arguments);
+ static TIntermAggregate *CreateConstructor(
+ const TType &type,
+ const std::initializer_list<TIntermNode *> &arguments);
+ ~TIntermAggregate() override {}
+
+ // Note: only supported for nodes that can be a part of an expression.
+ TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); }
+
+ TIntermAggregate *shallowCopy() const;
+
+ bool hasConstantValue() const override;
+ bool isConstantNullValue() const override;
+ const TConstantUnion *getConstantValue() const override;
+
+ TIntermAggregate *getAsAggregate() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ bool hasSideEffects() const override;
+
+ TIntermTyped *fold(TDiagnostics *diagnostics) override;
+
+ TIntermSequence *getSequence() override { return &mArguments; }
+ const TIntermSequence *getSequence() const override { return &mArguments; }
+
+ void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
+ bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
+
+ const TFunction *getFunction() const { return mFunction; }
+
+ // Get the function name to display to the user in an error message.
+ const char *functionName() const;
+
+ protected:
+ TIntermSequence mArguments;
+
+ // If set to true, replace the built-in function call with an emulated one
+ // to work around driver bugs. Only for calls mapped to ops other than EOpCall*.
+ bool mUseEmulatedFunction;
+
+ const TFunction *const mFunction;
+
+ private:
+ TIntermAggregate(const TFunction *func,
+ const TType &type,
+ TOperator op,
+ TIntermSequence *arguments);
+
+ TIntermAggregate(const TIntermAggregate &node); // note: not deleted, just private!
+
+ void setPrecisionAndQualifier();
+ TPrecision derivePrecision() const override;
+ void propagatePrecision(TPrecision precision) override;
+
+ bool areChildrenConstQualified();
+};
+
+// A list of statements. Either the root node which contains declarations and function definitions,
+// or a block that can be marked with curly braces {}.
+class TIntermBlock : public TIntermNode, public TIntermAggregateBase
+{
+ public:
+ TIntermBlock() : TIntermNode(), mIsTreeRoot(false) {}
+ TIntermBlock(std::initializer_list<TIntermNode *> stmts);
+ ~TIntermBlock() override {}
+
+ TIntermBlock *getAsBlock() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+ void replaceAllChildren(const TIntermSequence &newStatements);
+
+ // Only intended for initially building the block.
+ void appendStatement(TIntermNode *statement);
+ void insertStatement(size_t insertPosition, TIntermNode *statement);
+
+ TIntermSequence *getSequence() override { return &mStatements; }
+ const TIntermSequence *getSequence() const override { return &mStatements; }
+
+ TIntermBlock *deepCopy() const override { return new TIntermBlock(*this); }
+
+ void setIsTreeRoot() { mIsTreeRoot = true; }
+ bool isTreeRoot() const { return mIsTreeRoot; }
+
+ protected:
+ TIntermSequence mStatements;
+
+ // Used to distinguish the tree root from the other blocks. When validating the AST, some
+ // validations are not applicable if not run on the entire tree and are thus skipped.
+ bool mIsTreeRoot;
+
+ private:
+ TIntermBlock(const TIntermBlock &);
+};
+
+// Function prototype. May be in the AST either as a function prototype declaration or as a part of
+// a function definition. The type of the node is the function return type.
+class TIntermFunctionPrototype : public TIntermTyped
+{
+ public:
+ TIntermFunctionPrototype(const TFunction *function);
+ ~TIntermFunctionPrototype() override {}
+
+ TIntermFunctionPrototype *getAsFunctionPrototypeNode() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ const TType &getType() const override;
+
+ TIntermTyped *deepCopy() const override
+ {
+ UNREACHABLE();
+ return nullptr;
+ }
+ bool hasSideEffects() const override
+ {
+ UNREACHABLE();
+ return true;
+ }
+
+ const TFunction *getFunction() const { return mFunction; }
+
+ protected:
+ const TFunction *const mFunction;
+};
+
+// Node for function definitions. The prototype child node stores the function header including
+// parameters, and the body child node stores the function body.
+class TIntermFunctionDefinition : public TIntermNode
+{
+ public:
+ TIntermFunctionDefinition(TIntermFunctionPrototype *prototype, TIntermBlock *body)
+ : TIntermNode(), mPrototype(prototype), mBody(body)
+ {
+ ASSERT(prototype != nullptr);
+ ASSERT(body != nullptr);
+ }
+
+ TIntermFunctionDefinition *getAsFunctionDefinition() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermFunctionPrototype *getFunctionPrototype() const { return mPrototype; }
+ TIntermBlock *getBody() const { return mBody; }
+
+ const TFunction *getFunction() const { return mPrototype->getFunction(); }
+
+ TIntermNode *deepCopy() const override
+ {
+ UNREACHABLE();
+ return nullptr;
+ }
+
+ private:
+ TIntermFunctionPrototype *mPrototype;
+ TIntermBlock *mBody;
+};
+
+// Struct, interface block or variable declaration. Can contain multiple variable declarators.
+class TIntermDeclaration : public TIntermNode, public TIntermAggregateBase
+{
+ public:
+ TIntermDeclaration() : TIntermNode() {}
+ TIntermDeclaration(const TVariable *var, TIntermTyped *initExpr);
+ TIntermDeclaration(std::initializer_list<const TVariable *> declarators);
+ TIntermDeclaration(std::initializer_list<TIntermTyped *> declarators);
+ ~TIntermDeclaration() override {}
+
+ TIntermDeclaration *getAsDeclarationNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ // Only intended for initially building the declaration.
+ // The declarator node should be either TIntermSymbol or TIntermBinary with op set to
+ // EOpInitialize.
+ void appendDeclarator(TIntermTyped *declarator);
+
+ TIntermSequence *getSequence() override { return &mDeclarators; }
+ const TIntermSequence *getSequence() const override { return &mDeclarators; }
+
+ TIntermDeclaration *deepCopy() const override
+ {
+ // Note: This is only useful as support for deepCopy of TIntermBlock and TIntermLoop, but is
+ // not sufficient as it will be redeclaring the same TVariable. If a function body is
+ // duplicated for example, it means that both functions reference the same TVariable pointer
+ // which works, but is technically not correct. In particular, maps with TVariable * as key
+ // can get confused.
+ //
+ // After deepCopy() is issued, ReplaceVariables must be used to replace every declared
+ // variable with a duplicate. This is NOT automatically done when deepCopy-ing TIntermBlock
+ // and TIntermLoop nodes.
+ return new TIntermDeclaration(*this);
+ }
+
+ protected:
+ TIntermDeclaration(const TIntermDeclaration &node);
+
+ TIntermSequence mDeclarators;
+};
+
+// Specialized declarations for attributing invariance.
+class TIntermGlobalQualifierDeclaration : public TIntermNode
+{
+ public:
+ TIntermGlobalQualifierDeclaration(TIntermSymbol *symbol,
+ bool isPrecise,
+ const TSourceLoc &line);
+
+ virtual TIntermGlobalQualifierDeclaration *getAsGlobalQualifierDeclarationNode() override
+ {
+ return this;
+ }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ TIntermSymbol *getSymbol() { return mSymbol; }
+ bool isInvariant() const { return !mIsPrecise; }
+ bool isPrecise() const { return mIsPrecise; }
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermGlobalQualifierDeclaration *deepCopy() const override
+ {
+ return new TIntermGlobalQualifierDeclaration(*this);
+ }
+
+ private:
+ TIntermSymbol *mSymbol;
+ // Either |precise| or |invariant|, determined based on this flag.
+ bool mIsPrecise;
+
+ TIntermGlobalQualifierDeclaration(const TIntermGlobalQualifierDeclaration &);
+};
+
+// For ternary operators like a ? b : c.
+class TIntermTernary : public TIntermExpression
+{
+ public:
+ TIntermTernary(TIntermTyped *cond, TIntermTyped *trueExpression, TIntermTyped *falseExpression);
+
+ TIntermTernary *getAsTernaryNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermTyped *getCondition() const { return mCondition; }
+ TIntermTyped *getTrueExpression() const { return mTrueExpression; }
+ TIntermTyped *getFalseExpression() const { return mFalseExpression; }
+
+ TIntermTyped *deepCopy() const override { return new TIntermTernary(*this); }
+
+ bool hasSideEffects() const override
+ {
+ return mCondition->hasSideEffects() || mTrueExpression->hasSideEffects() ||
+ mFalseExpression->hasSideEffects();
+ }
+
+ TIntermTyped *fold(TDiagnostics *diagnostics) override;
+
+ private:
+ TIntermTernary(const TIntermTernary &node); // Note: not deleted, just private!
+
+ static TQualifier DetermineQualifier(TIntermTyped *cond,
+ TIntermTyped *trueExpression,
+ TIntermTyped *falseExpression);
+ TPrecision derivePrecision() const override;
+ void propagatePrecision(TPrecision precision) override;
+
+ TIntermTyped *mCondition;
+ TIntermTyped *mTrueExpression;
+ TIntermTyped *mFalseExpression;
+};
+
+class TIntermIfElse : public TIntermNode
+{
+ public:
+ TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB);
+
+ TIntermIfElse *getAsIfElseNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermTyped *getCondition() const { return mCondition; }
+ TIntermBlock *getTrueBlock() const { return mTrueBlock; }
+ TIntermBlock *getFalseBlock() const { return mFalseBlock; }
+
+ TIntermIfElse *deepCopy() const override { return new TIntermIfElse(*this); }
+
+ protected:
+ TIntermTyped *mCondition;
+ TIntermBlock *mTrueBlock;
+ TIntermBlock *mFalseBlock;
+
+ private:
+ TIntermIfElse(const TIntermIfElse &);
+};
+
+//
+// Switch statement.
+//
+class TIntermSwitch : public TIntermNode
+{
+ public:
+ TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList);
+
+ TIntermSwitch *getAsSwitchNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermTyped *getInit() { return mInit; }
+ TIntermBlock *getStatementList() { return mStatementList; }
+
+ // Must be called with a non-null statementList.
+ void setStatementList(TIntermBlock *statementList);
+
+ TIntermSwitch *deepCopy() const override { return new TIntermSwitch(*this); }
+
+ protected:
+ TIntermTyped *mInit;
+ TIntermBlock *mStatementList;
+
+ private:
+ TIntermSwitch(const TIntermSwitch &);
+};
+
+//
+// Case label.
+//
+class TIntermCase : public TIntermNode
+{
+ public:
+ TIntermCase(TIntermTyped *condition) : TIntermNode(), mCondition(condition) {}
+
+ TIntermCase *getAsCaseNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ bool hasCondition() const { return mCondition != nullptr; }
+ TIntermTyped *getCondition() const { return mCondition; }
+
+ TIntermCase *deepCopy() const override { return new TIntermCase(*this); }
+
+ protected:
+ TIntermTyped *mCondition;
+
+ private:
+ TIntermCase(const TIntermCase &);
+};
+
+//
+// Preprocessor Directive.
+// #ifdef, #define, #if, #endif, etc.
+//
+
+enum class PreprocessorDirective
+{
+ Define,
+ Ifdef,
+ If,
+ Endif,
+};
+
+class TIntermPreprocessorDirective final : public TIntermNode
+{
+ public:
+ // This could also take an ImmutableString as an argument.
+ TIntermPreprocessorDirective(PreprocessorDirective directive, ImmutableString command);
+ ~TIntermPreprocessorDirective() final;
+
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+ bool replaceChildNode(TIntermNode *, TIntermNode *) final { return false; }
+
+ TIntermPreprocessorDirective *getAsPreprocessorDirective() final { return this; }
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+
+ PreprocessorDirective getDirective() const { return mDirective; }
+ const ImmutableString &getCommand() const { return mCommand; }
+
+ TIntermPreprocessorDirective *deepCopy() const override
+ {
+ return new TIntermPreprocessorDirective(*this);
+ }
+
+ private:
+ PreprocessorDirective mDirective;
+ ImmutableString mCommand;
+
+ TIntermPreprocessorDirective(const TIntermPreprocessorDirective &);
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_INTERMNODE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp b/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp
new file mode 100644
index 0000000000..74a1b55807
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp
@@ -0,0 +1,37 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/IsASTDepthBelowLimit.h"
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Traverse the tree and compute max depth. Takes a maximum depth limit to prevent stack overflow.
+class MaxDepthTraverser : public TIntermTraverser
+{
+ public:
+ MaxDepthTraverser(int depthLimit) : TIntermTraverser(true, false, false, nullptr)
+ {
+ setMaxAllowedDepth(depthLimit);
+ }
+};
+
+} // anonymous namespace
+
+bool IsASTDepthBelowLimit(TIntermNode *root, int maxDepth)
+{
+ MaxDepthTraverser traverser(maxDepth + 1);
+ root->traverse(&traverser);
+
+ return traverser.getMaxDepth() <= maxDepth;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.h b/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.h
new file mode 100644
index 0000000000..17f85b513a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.h
@@ -0,0 +1,20 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// IsASTDepthBelowLimit: Check whether AST depth is below a specific limit.
+
+#ifndef COMPILER_TRANSLATOR_ISASTDEPTHBELOWLIMIT_H_
+#define COMPILER_TRANSLATOR_ISASTDEPTHBELOWLIMIT_H_
+
+namespace sh
+{
+
+class TIntermNode;
+
+bool IsASTDepthBelowLimit(TIntermNode *root, int maxDepth);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_ISASTDEPTHBELOWLIMIT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Operator.cpp b/gfx/angle/checkout/src/compiler/translator/Operator.cpp
new file mode 100644
index 0000000000..3b636ad2af
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Operator.cpp
@@ -0,0 +1,171 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/Operator_autogen.h"
+
+#include "common/debug.h"
+
+namespace sh
+{
+
+const char *GetOperatorString(TOperator op)
+{
+ switch (op)
+ {
+ // Note: EOpNull and EOpCall* can't be handled here.
+
+ case EOpNegative:
+ return "-";
+ case EOpPositive:
+ return "+";
+ case EOpLogicalNot:
+ return "!";
+ case EOpBitwiseNot:
+ return "~";
+
+ case EOpPostIncrement:
+ return "++";
+ case EOpPostDecrement:
+ return "--";
+ case EOpPreIncrement:
+ return "++";
+ case EOpPreDecrement:
+ return "--";
+
+ case EOpArrayLength:
+ return ".length()";
+
+ case EOpAdd:
+ return "+";
+ case EOpSub:
+ return "-";
+ case EOpMul:
+ return "*";
+ case EOpDiv:
+ return "/";
+ case EOpIMod:
+ return "%";
+
+ case EOpEqual:
+ return "==";
+ case EOpNotEqual:
+ return "!=";
+ case EOpLessThan:
+ return "<";
+ case EOpGreaterThan:
+ return ">";
+ case EOpLessThanEqual:
+ return "<=";
+ case EOpGreaterThanEqual:
+ return ">=";
+
+ case EOpComma:
+ return ",";
+
+ // Fall-through.
+ case EOpVectorTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpMatrixTimesMatrix:
+ return "*";
+
+ case EOpLogicalOr:
+ return "||";
+ case EOpLogicalXor:
+ return "^^";
+ case EOpLogicalAnd:
+ return "&&";
+
+ case EOpBitShiftLeft:
+ return "<<";
+ case EOpBitShiftRight:
+ return ">>";
+
+ case EOpBitwiseAnd:
+ return "&";
+ case EOpBitwiseXor:
+ return "^";
+ case EOpBitwiseOr:
+ return "|";
+
+ // Fall-through.
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ return "[]";
+
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ return ".";
+
+ case EOpAssign:
+ case EOpInitialize:
+ return "=";
+ case EOpAddAssign:
+ return "+=";
+ case EOpSubAssign:
+ return "-=";
+
+ // Fall-through.
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+ return "*=";
+
+ case EOpDivAssign:
+ return "/=";
+ case EOpIModAssign:
+ return "%=";
+ case EOpBitShiftLeftAssign:
+ return "<<=";
+ case EOpBitShiftRightAssign:
+ return ">>=";
+ case EOpBitwiseAndAssign:
+ return "&=";
+ case EOpBitwiseXorAssign:
+ return "^=";
+ case EOpBitwiseOrAssign:
+ return "|=";
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return "";
+}
+
+bool IsAssignment(TOperator op)
+{
+ switch (op)
+ {
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+ case EOpAssign:
+ case EOpAddAssign:
+ case EOpSubAssign:
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+ case EOpDivAssign:
+ case EOpIModAssign:
+ case EOpBitShiftLeftAssign:
+ case EOpBitShiftRightAssign:
+ case EOpBitwiseAndAssign:
+ case EOpBitwiseXorAssign:
+ case EOpBitwiseOrAssign:
+ return true;
+ default:
+ return false;
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Operator_autogen.h b/gfx/angle/checkout/src/compiler/translator/Operator_autogen.h
new file mode 100644
index 0000000000..153dcb6339
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Operator_autogen.h
@@ -0,0 +1,578 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_function_declarations.txt.
+//
+// Copyright 2021 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Operator_autogen.h:
+// Operators used by the high-level (parse tree) representation.
+
+#ifndef COMPILER_TRANSLATOR_OPERATOR_AUTOGEN_H_
+#define COMPILER_TRANSLATOR_OPERATOR_AUTOGEN_H_
+
+#include <stdint.h>
+
+namespace sh
+{
+
+enum TOperator : uint16_t
+{
+ EOpNull, // if in a node, should only mean a node is still being built
+
+ // Call a function defined in the AST. This might be a user-defined function or a function
+ // inserted by an AST transformation.
+ EOpCallFunctionInAST,
+
+ // Call an internal helper function with a raw implementation - the implementation can't be
+ // subject to AST transformations. Raw functions have a few constraints to keep them compatible
+ // with AST traversers:
+ // * They should not return arrays.
+ // * They should not have out parameters.
+ //
+ // DEPRECATED; DO NOT USE. TODO: remove this. http://anglebug.com/6059
+ //
+ EOpCallInternalRawFunction,
+
+ //
+ // Branch (TIntermBranch)
+ //
+
+ EOpKill, // Fragment only
+ EOpReturn,
+ EOpBreak,
+ EOpContinue,
+
+ //
+ // Constructor (TIntermAggregate)
+ //
+
+ EOpConstruct,
+
+ //
+ // Unary operators with special GLSL syntax (TIntermUnary).
+ //
+
+ EOpNegative,
+ EOpPositive,
+ EOpLogicalNot,
+ EOpBitwiseNot,
+
+ EOpPostIncrement,
+ EOpPostDecrement,
+ EOpPreIncrement,
+ EOpPreDecrement,
+
+ EOpArrayLength,
+
+ //
+ // Binary operators with special GLSL syntax (TIntermBinary).
+ //
+
+ EOpAdd,
+ EOpSub,
+ EOpMul,
+ EOpDiv,
+ EOpIMod,
+
+ EOpEqual,
+ EOpNotEqual,
+ EOpLessThan,
+ EOpGreaterThan,
+ EOpLessThanEqual,
+ EOpGreaterThanEqual,
+
+ EOpComma,
+
+ EOpVectorTimesScalar,
+ EOpVectorTimesMatrix,
+ EOpMatrixTimesVector,
+ EOpMatrixTimesScalar,
+ EOpMatrixTimesMatrix,
+
+ EOpLogicalOr,
+ EOpLogicalXor,
+ EOpLogicalAnd,
+
+ EOpBitShiftLeft,
+ EOpBitShiftRight,
+
+ EOpBitwiseAnd,
+ EOpBitwiseXor,
+ EOpBitwiseOr,
+
+ EOpIndexDirect,
+ EOpIndexIndirect,
+ EOpIndexDirectStruct,
+ EOpIndexDirectInterfaceBlock,
+
+ //
+ // Moves (TIntermBinary)
+ //
+
+ EOpAssign,
+ EOpInitialize,
+ EOpAddAssign,
+ EOpSubAssign,
+
+ EOpMulAssign,
+ EOpVectorTimesMatrixAssign,
+ EOpVectorTimesScalarAssign,
+ EOpMatrixTimesScalarAssign,
+ EOpMatrixTimesMatrixAssign,
+
+ EOpDivAssign,
+ EOpIModAssign,
+ EOpBitShiftLeftAssign,
+ EOpBitShiftRightAssign,
+ EOpBitwiseAndAssign,
+ EOpBitwiseXorAssign,
+ EOpBitwiseOrAssign,
+
+ // Not an op, but a marker for the start of built-in ops.
+ EOpLastNonBuiltIn = EOpBitwiseOrAssign,
+
+ //
+ // Built-in functions mapped to operators (either unary (TIntermUnary) or with multiple
+ // parameters (TIntermAggregate))
+ //
+
+ // Group Math
+
+ // Group MathTrigonometric
+ EOpRadians, // Unary
+ EOpDegrees, // Unary
+ EOpSin, // Unary
+ EOpCos, // Unary
+ EOpTan, // Unary
+ EOpAsin, // Unary
+ EOpAcos, // Unary
+ EOpAtan,
+ EOpSinh, // Unary
+ EOpCosh, // Unary
+ EOpTanh, // Unary
+ EOpAsinh, // Unary
+ EOpAcosh, // Unary
+ EOpAtanh, // Unary
+
+ // Group MathExponential
+ EOpPow,
+ EOpExp, // Unary
+ EOpLog, // Unary
+ EOpExp2, // Unary
+ EOpLog2, // Unary
+ EOpSqrt, // Unary
+ EOpInversesqrt, // Unary
+
+ // Group MathCommon
+ EOpAbs, // Unary
+ EOpSign, // Unary
+ EOpFloor, // Unary
+ EOpTrunc, // Unary
+ EOpRound, // Unary
+ EOpRoundEven, // Unary
+ EOpCeil, // Unary
+ EOpFract, // Unary
+ EOpMod,
+ EOpMin,
+ EOpMax,
+ EOpClamp,
+ EOpMix,
+ EOpStep,
+ EOpSmoothstep,
+ EOpModf,
+ EOpIsnan, // Unary
+ EOpIsinf, // Unary
+ EOpFloatBitsToInt, // Unary
+ EOpFloatBitsToUint, // Unary
+ EOpIntBitsToFloat, // Unary
+ EOpUintBitsToFloat, // Unary
+ EOpFma,
+ EOpFrexp,
+ EOpLdexp,
+ EOpPackSnorm2x16, // Unary
+ EOpPackHalf2x16, // Unary
+ EOpUnpackSnorm2x16, // Unary
+ EOpUnpackHalf2x16, // Unary
+ EOpPackUnorm2x16, // Unary
+ EOpUnpackUnorm2x16, // Unary
+ EOpPackUnorm4x8, // Unary
+ EOpPackSnorm4x8, // Unary
+ EOpUnpackUnorm4x8, // Unary
+ EOpUnpackSnorm4x8, // Unary
+ EOpPackDouble2x32, // Unary
+ EOpUnpackDouble2x32, // Unary
+
+ // Group MathGeometric
+ EOpLength, // Unary
+ EOpDistance,
+ EOpDot,
+ EOpCross,
+ EOpNormalize, // Unary
+ EOpFaceforward,
+ EOpReflect,
+ EOpRefract,
+
+ // Group MathGeometricVS
+ EOpFtransform,
+
+ // Group MathMatrix
+ EOpMatrixCompMult,
+ EOpOuterProduct,
+ EOpTranspose, // Unary
+ EOpDeterminant, // Unary
+ EOpInverse, // Unary
+
+ // Group MathVector
+ EOpLessThanComponentWise,
+ EOpLessThanEqualComponentWise,
+ EOpGreaterThanComponentWise,
+ EOpGreaterThanEqualComponentWise,
+ EOpEqualComponentWise,
+ EOpNotEqualComponentWise,
+ EOpAny, // Unary
+ EOpAll, // Unary
+ EOpNotComponentWise, // Unary
+
+ // Group MathInteger
+ EOpBitfieldExtract,
+ EOpBitfieldInsert,
+ EOpBitfieldReverse, // Unary
+ EOpBitCount, // Unary
+ EOpFindLSB, // Unary
+ EOpFindMSB, // Unary
+ EOpUaddCarry,
+ EOpUsubBorrow,
+ EOpUmulExtended,
+ EOpImulExtended,
+
+ // Group Texture
+
+ // Group TextureFirstVersions
+ EOpTexture2D,
+ EOpTexture2DProj,
+ EOpTextureCube,
+ EOpTexture1D,
+ EOpTexture1DProj,
+ EOpTexture3D,
+ EOpTexture3DProj,
+ EOpShadow1D,
+ EOpShadow1DProj,
+ EOpShadow2D,
+ EOpShadow2DProj,
+ EOpShadow2DEXT,
+ EOpShadow2DProjEXT,
+ EOpTexture2DRect,
+ EOpTexture2DRectProj,
+ EOpTexture2DGradEXT,
+ EOpTexture2DProjGradEXT,
+ EOpTextureCubeGradEXT,
+ EOpTextureVideoWEBGL,
+
+ // Group TextureFirstVersionsBias
+ EOpTexture2DBias,
+ EOpTexture2DProjBias,
+ EOpTextureCubeBias,
+ EOpTexture3DBias,
+ EOpTexture3DProjBias,
+ EOpTexture1DBias,
+ EOpTexture1DProjBias,
+ EOpShadow1DBias,
+ EOpShadow1DProjBias,
+ EOpShadow2DBias,
+ EOpShadow2DProjBias,
+
+ // Group TextureFirstVersionsLod
+ EOpTexture2DLod,
+ EOpTexture2DProjLod,
+ EOpTextureCubeLod,
+ EOpTexture1DLod,
+ EOpTexture1DProjLod,
+ EOpShadow1DLod,
+ EOpShadow1DProjLod,
+ EOpShadow2DLod,
+ EOpShadow2DProjLod,
+ EOpTexture3DLod,
+ EOpTexture3DProjLod,
+
+ // Group TextureFirstVersionsLodVS
+ EOpTexture2DLodVS,
+ EOpTexture2DProjLodVS,
+ EOpTextureCubeLodVS,
+
+ // Group TextureFirstVersionsLodFS
+ EOpTexture2DLodEXTFS,
+ EOpTexture2DProjLodEXTFS,
+ EOpTextureCubeLodEXTFS,
+
+ // Group TextureNoBias
+ EOpTexture,
+ EOpTextureProj,
+ EOpTextureLod,
+ EOpTextureSize,
+ EOpTextureProjLod,
+ EOpTexelFetch,
+ EOpTextureGrad,
+ EOpTextureProjGrad,
+ EOpTextureQueryLevels,
+ EOpTextureSamples,
+
+ // Group TextureBias
+ EOpTextureBias,
+ EOpTextureProjBias,
+
+ // Group TextureQueryLod
+ EOpTextureQueryLod,
+
+ // Group TextureOffsetNoBias
+ EOpTextureOffset,
+ EOpTextureProjOffset,
+ EOpTextureLodOffset,
+ EOpTextureProjLodOffset,
+ EOpTexelFetchOffset,
+ EOpTextureGradOffset,
+ EOpTextureProjGradOffset,
+
+ // Group TextureOffsetBias
+ EOpTextureOffsetBias,
+ EOpTextureProjOffsetBias,
+
+ // Group TextureGather
+ EOpTextureGather,
+
+ // Group TextureGatherOffset
+
+ // Group TextureGatherOffsetNoComp
+ EOpTextureGatherOffset,
+
+ // Group TextureGatherOffsetComp
+ EOpTextureGatherOffsetComp,
+
+ // Group TextureGatherOffsets
+
+ // Group TextureGatherOffsetsNoComp
+ EOpTextureGatherOffsets,
+
+ // Group TextureGatherOffsetsComp
+ EOpTextureGatherOffsetsComp,
+
+ // Group EXT_YUV_target
+ EOpRgb_2_yuv,
+ EOpYuv_2_rgb,
+
+ // Group DerivativesFS
+ EOpDFdx,
+ EOpDFdy,
+ EOpFwidth,
+ EOpDFdxFine,
+ EOpDFdyFine,
+ EOpDFdxCoarse,
+ EOpDFdyCoarse,
+ EOpFwidthFine,
+ EOpFwidthCoarse,
+
+ // Group InterpolationFS
+ EOpInterpolateAtCentroid,
+ EOpInterpolateAtSample,
+ EOpInterpolateAtOffset,
+
+ // Group AtomicCounter
+ EOpAtomicCounter,
+ EOpAtomicCounterIncrement,
+ EOpAtomicCounterDecrement,
+ EOpAtomicCounterAdd,
+ EOpAtomicCounterSubtract,
+ EOpAtomicCounterMin,
+ EOpAtomicCounterMax,
+ EOpAtomicCounterAnd,
+ EOpAtomicCounterOr,
+ EOpAtomicCounterXor,
+ EOpAtomicCounterExchange,
+ EOpAtomicCounterCompSwap,
+
+ // Group AtomicMemory
+ EOpAtomicAdd,
+ EOpAtomicMin,
+ EOpAtomicMax,
+ EOpAtomicAnd,
+ EOpAtomicOr,
+ EOpAtomicXor,
+ EOpAtomicExchange,
+ EOpAtomicCompSwap,
+
+ // Group Image
+ EOpImageSize,
+ EOpImageSamples,
+
+ // Group ImageStore
+ EOpImageStore,
+
+ // Group ImageLoad
+ EOpImageLoad,
+
+ // Group ImageAtomic
+ EOpImageAtomicAdd,
+ EOpImageAtomicMin,
+ EOpImageAtomicMax,
+ EOpImageAtomicAnd,
+ EOpImageAtomicOr,
+ EOpImageAtomicXor,
+ EOpImageAtomicExchange,
+ EOpImageAtomicCompSwap,
+
+ // Group PixelLocal
+
+ // Group PixelLocalLoad
+ EOpPixelLocalLoadANGLE,
+
+ // Group PixelLocalStore
+ EOpPixelLocalStoreANGLE,
+
+ // Group FragmentSynchronization
+ EOpBeginInvocationInterlockNV,
+ EOpEndInvocationInterlockNV,
+ EOpBeginFragmentShaderOrderingINTEL,
+ EOpBeginInvocationInterlockARB,
+ EOpEndInvocationInterlockARB,
+
+ // Group Noise
+ EOpNoise1,
+ EOpNoise2,
+ EOpNoise3,
+ EOpNoise4,
+
+ // Group Barrier
+ EOpMemoryBarrier,
+ EOpMemoryBarrierAtomicCounter,
+ EOpMemoryBarrierBuffer,
+ EOpMemoryBarrierImage,
+
+ // Group ESSL310CS
+ EOpBarrier,
+ EOpMemoryBarrierShared,
+ EOpGroupMemoryBarrier,
+
+ // Group ESSL310TCS
+ EOpBarrierTCS,
+
+ // Group GS
+ EOpEmitVertex,
+ EOpEndPrimitive,
+ EOpEmitStreamVertex,
+ EOpEndStreamPrimitive,
+
+ // Group SubpassInput
+ EOpSubpassLoad,
+
+ // Group ShaderInvocationGroup
+ EOpAnyInvocation,
+ EOpAllInvocations,
+ EOpAllInvocationsEqual,
+};
+
+// Returns the string corresponding to the operator in GLSL. For built-in functions use the
+// function name directly.
+const char *GetOperatorString(TOperator op);
+
+// Say whether or not a binary or unary operation changes the value of a variable.
+bool IsAssignment(TOperator op);
+
+namespace BuiltInGroup
+{
+static inline bool IsBuiltIn(TOperator op)
+{
+ return op > EOpLastNonBuiltIn;
+}
+static inline bool IsMath(TOperator op)
+{
+ return op >= EOpRadians && op <= EOpImulExtended;
+}
+static inline bool IsTextureOffsetNoBias(TOperator op)
+{
+ return op >= EOpTextureOffset && op <= EOpTextureProjGradOffset;
+}
+static inline bool IsTextureOffsetBias(TOperator op)
+{
+ return op >= EOpTextureOffsetBias && op <= EOpTextureProjOffsetBias;
+}
+static inline bool IsTextureGatherOffsetNoComp(TOperator op)
+{
+ return op >= EOpTextureGatherOffset && op <= EOpTextureGatherOffset;
+}
+static inline bool IsTextureGatherOffsetComp(TOperator op)
+{
+ return op >= EOpTextureGatherOffsetComp && op <= EOpTextureGatherOffsetComp;
+}
+static inline bool IsTextureGatherOffset(TOperator op)
+{
+ return op >= EOpTextureGatherOffset && op <= EOpTextureGatherOffsetComp;
+}
+static inline bool IsTextureGatherOffsetsNoComp(TOperator op)
+{
+ return op >= EOpTextureGatherOffsets && op <= EOpTextureGatherOffsets;
+}
+static inline bool IsTextureGatherOffsetsComp(TOperator op)
+{
+ return op >= EOpTextureGatherOffsetsComp && op <= EOpTextureGatherOffsetsComp;
+}
+static inline bool IsTextureGatherOffsets(TOperator op)
+{
+ return op >= EOpTextureGatherOffsets && op <= EOpTextureGatherOffsetsComp;
+}
+static inline bool IsTextureGather(TOperator op)
+{
+ return op >= EOpTextureGather && op <= EOpTextureGatherOffsetsComp;
+}
+static inline bool IsTexture(TOperator op)
+{
+ return op >= EOpTexture2D && op <= EOpTextureGatherOffsetsComp;
+}
+static inline bool IsDerivativesFS(TOperator op)
+{
+ return op >= EOpDFdx && op <= EOpFwidthCoarse;
+}
+static inline bool IsInterpolationFS(TOperator op)
+{
+ return op >= EOpInterpolateAtCentroid && op <= EOpInterpolateAtOffset;
+}
+static inline bool IsAtomicCounter(TOperator op)
+{
+ return op >= EOpAtomicCounter && op <= EOpAtomicCounterCompSwap;
+}
+static inline bool IsAtomicMemory(TOperator op)
+{
+ return op >= EOpAtomicAdd && op <= EOpAtomicCompSwap;
+}
+static inline bool IsImageStore(TOperator op)
+{
+ return op >= EOpImageStore && op <= EOpImageStore;
+}
+static inline bool IsImageLoad(TOperator op)
+{
+ return op >= EOpImageLoad && op <= EOpImageLoad;
+}
+static inline bool IsImageAtomic(TOperator op)
+{
+ return op >= EOpImageAtomicAdd && op <= EOpImageAtomicCompSwap;
+}
+static inline bool IsImage(TOperator op)
+{
+ return op >= EOpImageSize && op <= EOpImageAtomicCompSwap;
+}
+static inline bool IsPixelLocalLoad(TOperator op)
+{
+ return op >= EOpPixelLocalLoadANGLE && op <= EOpPixelLocalLoadANGLE;
+}
+static inline bool IsPixelLocalStore(TOperator op)
+{
+ return op >= EOpPixelLocalStoreANGLE && op <= EOpPixelLocalStoreANGLE;
+}
+static inline bool IsPixelLocal(TOperator op)
+{
+ return op >= EOpPixelLocalLoadANGLE && op <= EOpPixelLocalStoreANGLE;
+}
+} // namespace BuiltInGroup
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OPERATOR_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputESSL.cpp b/gfx/angle/checkout/src/compiler/translator/OutputESSL.cpp
new file mode 100644
index 0000000000..95c7e1e0be
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputESSL.cpp
@@ -0,0 +1,55 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/OutputESSL.h"
+
+namespace sh
+{
+
+TOutputESSL::TOutputESSL(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions)
+ : TOutputGLSLBase(compiler, objSink, compileOptions)
+{}
+
+bool TOutputESSL::writeVariablePrecision(TPrecision precision)
+{
+ if (precision == EbpUndefined)
+ return false;
+
+ if (precision == EbpHigh && !isHighPrecisionSupported())
+ {
+ precision = EbpMedium;
+ }
+
+ TInfoSinkBase &out = objSink();
+ out << getPrecisionString(precision);
+ return true;
+}
+
+ImmutableString TOutputESSL::translateTextureFunction(const ImmutableString &name,
+ const ShCompileOptions &option)
+{
+ // Check WEBGL_video_texture invocation first.
+ if (name == "textureVideoWEBGL")
+ {
+ if (option.takeVideoTextureAsExternalOES)
+ {
+ // TODO(http://anglebug.com/3889): Implement external image situation.
+ UNIMPLEMENTED();
+ return ImmutableString("");
+ }
+ else
+ {
+ // Default translating textureVideoWEBGL to texture2D.
+ return ImmutableString("texture2D");
+ }
+ }
+
+ return name;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputESSL.h b/gfx/angle/checkout/src/compiler/translator/OutputESSL.h
new file mode 100644
index 0000000000..9d14de2081
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputESSL.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_OUTPUTESSL_H_
+#define COMPILER_TRANSLATOR_OUTPUTESSL_H_
+
+#include "compiler/translator/OutputGLSLBase.h"
+
+namespace sh
+{
+
+class TOutputESSL : public TOutputGLSLBase
+{
+ public:
+ TOutputESSL(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions);
+
+ protected:
+ bool writeVariablePrecision(TPrecision precision) override;
+ ImmutableString translateTextureFunction(const ImmutableString &name,
+ const ShCompileOptions &option) override;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OUTPUTESSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp
new file mode 100644
index 0000000000..0045a76dfc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp
@@ -0,0 +1,122 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/OutputGLSL.h"
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+TOutputGLSL::TOutputGLSL(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions)
+ : TOutputGLSLBase(compiler, objSink, compileOptions)
+{}
+
+bool TOutputGLSL::writeVariablePrecision(TPrecision)
+{
+ return false;
+}
+
+void TOutputGLSL::visitSymbol(TIntermSymbol *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ // All the special cases are built-ins, so if it's not a built-in we can return early.
+ if (node->variable().symbolType() != SymbolType::BuiltIn)
+ {
+ TOutputGLSLBase::visitSymbol(node);
+ return;
+ }
+
+ // Some built-ins get a special translation.
+ const ImmutableString &name = node->getName();
+ if (name == "gl_FragDepthEXT")
+ {
+ out << "gl_FragDepth";
+ }
+ else if (name == "gl_FragColor" && sh::IsGLSL130OrNewer(getShaderOutput()))
+ {
+ out << "webgl_FragColor";
+ }
+ else if (name == "gl_FragData" && sh::IsGLSL130OrNewer(getShaderOutput()))
+ {
+ out << "webgl_FragData";
+ }
+ else if (name == "gl_SecondaryFragColorEXT")
+ {
+ out << "webgl_SecondaryFragColor";
+ }
+ else if (name == "gl_SecondaryFragDataEXT")
+ {
+ out << "webgl_SecondaryFragData";
+ }
+ else
+ {
+ TOutputGLSLBase::visitSymbol(node);
+ }
+}
+
+ImmutableString TOutputGLSL::translateTextureFunction(const ImmutableString &name,
+ const ShCompileOptions &option)
+{
+ // Check WEBGL_video_texture invocation first.
+ if (name == "textureVideoWEBGL")
+ {
+ if (option.takeVideoTextureAsExternalOES)
+ {
+ // TODO(http://anglebug.com/3889): Implement external image situation.
+ UNIMPLEMENTED();
+ return ImmutableString("");
+ }
+ else
+ {
+ // Default translating textureVideoWEBGL to texture2D.
+ return ImmutableString("texture2D");
+ }
+ }
+
+ static const char *simpleRename[] = {"texture2DLodEXT",
+ "texture2DLod",
+ "texture2DProjLodEXT",
+ "texture2DProjLod",
+ "textureCubeLodEXT",
+ "textureCubeLod",
+ "texture2DGradEXT",
+ "texture2DGradARB",
+ "texture2DProjGradEXT",
+ "texture2DProjGradARB",
+ "textureCubeGradEXT",
+ "textureCubeGradARB",
+ nullptr,
+ nullptr};
+ static const char *legacyToCoreRename[] = {
+ "texture2D", "texture", "texture2DProj", "textureProj", "texture2DLod", "textureLod",
+ "texture2DProjLod", "textureProjLod", "texture2DRect", "texture", "texture2DRectProj",
+ "textureProj", "textureCube", "texture", "textureCubeLod", "textureLod",
+ // Extensions
+ "texture2DLodEXT", "textureLod", "texture2DProjLodEXT", "textureProjLod",
+ "textureCubeLodEXT", "textureLod", "texture2DGradEXT", "textureGrad",
+ "texture2DProjGradEXT", "textureProjGrad", "textureCubeGradEXT", "textureGrad", "texture3D",
+ "texture", "texture3DProj", "textureProj", "texture3DLod", "textureLod", "texture3DProjLod",
+ "textureProjLod", "shadow2DEXT", "texture", "shadow2DProjEXT", "textureProj", nullptr,
+ nullptr};
+ const char **mapping =
+ (sh::IsGLSL130OrNewer(getShaderOutput())) ? legacyToCoreRename : simpleRename;
+
+ for (int i = 0; mapping[i] != nullptr; i += 2)
+ {
+ if (name == mapping[i])
+ {
+ return ImmutableString(mapping[i + 1]);
+ }
+ }
+
+ return name;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputGLSL.h b/gfx/angle/checkout/src/compiler/translator/OutputGLSL.h
new file mode 100644
index 0000000000..ff55e16a2a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputGLSL.h
@@ -0,0 +1,31 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_OUTPUTGLSL_H_
+#define COMPILER_TRANSLATOR_OUTPUTGLSL_H_
+
+#include "compiler/translator/OutputGLSLBase.h"
+
+namespace sh
+{
+
+class TOutputGLSL : public TOutputGLSLBase
+{
+ public:
+ TOutputGLSL(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions);
+
+ protected:
+ bool writeVariablePrecision(TPrecision) override;
+ void visitSymbol(TIntermSymbol *node) override;
+ ImmutableString translateTextureFunction(const ImmutableString &name,
+ const ShCompileOptions &option) override;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OUTPUTGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp b/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp
new file mode 100644
index 0000000000..9536fe1d03
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp
@@ -0,0 +1,1513 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/OutputGLSLBase.h"
+
+#include "angle_gl.h"
+#include "common/debug.h"
+#include "common/mathutil.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/util.h"
+
+#include <cfloat>
+
+namespace sh
+{
+
+namespace
+{
+
+bool isSingleStatement(TIntermNode *node)
+{
+ if (node->getAsFunctionDefinition())
+ {
+ return false;
+ }
+ else if (node->getAsBlock())
+ {
+ return false;
+ }
+ else if (node->getAsIfElseNode())
+ {
+ return false;
+ }
+ else if (node->getAsLoopNode())
+ {
+ return false;
+ }
+ else if (node->getAsSwitchNode())
+ {
+ return false;
+ }
+ else if (node->getAsCaseNode())
+ {
+ return false;
+ }
+ else if (node->getAsPreprocessorDirective())
+ {
+ return false;
+ }
+ return true;
+}
+
+class CommaSeparatedListItemPrefixGenerator
+{
+ public:
+ CommaSeparatedListItemPrefixGenerator() : mFirst(true) {}
+
+ private:
+ bool mFirst;
+
+ template <typename Stream>
+ friend Stream &operator<<(Stream &out, CommaSeparatedListItemPrefixGenerator &gen);
+};
+
+template <typename Stream>
+Stream &operator<<(Stream &out, CommaSeparatedListItemPrefixGenerator &gen)
+{
+ if (gen.mFirst)
+ {
+ gen.mFirst = false;
+ }
+ else
+ {
+ out << ", ";
+ }
+ return out;
+}
+
+} // namespace
+
+TOutputGLSLBase::TOutputGLSLBase(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions)
+ : TIntermTraverser(true, true, true, &compiler->getSymbolTable()),
+ mObjSink(objSink),
+ mDeclaringVariable(false),
+ mHashFunction(compiler->getHashFunction()),
+ mNameMap(compiler->getNameMap()),
+ mShaderType(compiler->getShaderType()),
+ mShaderVersion(compiler->getShaderVersion()),
+ mOutput(compiler->getOutputType()),
+ mHighPrecisionSupported(compiler->isHighPrecisionSupported()),
+ // If pixel local storage introduces new fragment outputs, we are now required to specify a
+ // location for _all_ fragment outputs, including previously valid outputs that had an
+ // implicit location of zero.
+ mAlwaysSpecifyFragOutLocation(compiler->hasPixelLocalStorageUniforms() &&
+ compileOptions.pls.type ==
+ ShPixelLocalStorageType::FramebufferFetch),
+ mCompileOptions(compileOptions)
+{}
+
+void TOutputGLSLBase::writeInvariantQualifier(const TType &type)
+{
+ if (!sh::RemoveInvariant(mShaderType, mShaderVersion, mOutput, mCompileOptions))
+ {
+ TInfoSinkBase &out = objSink();
+ out << "invariant ";
+ }
+}
+
+void TOutputGLSLBase::writePreciseQualifier(const TType &type)
+{
+ TInfoSinkBase &out = objSink();
+ out << "precise ";
+}
+
+void TOutputGLSLBase::writeFloat(TInfoSinkBase &out, float f)
+{
+ if ((gl::isInf(f) || gl::isNaN(f)) && mShaderVersion >= 300)
+ {
+ out << "uintBitsToFloat(" << gl::bitCast<uint32_t>(f) << "u)";
+ }
+ else
+ {
+ out << std::min(FLT_MAX, std::max(-FLT_MAX, f));
+ }
+}
+
+void TOutputGLSLBase::writeTriplet(Visit visit,
+ const char *preStr,
+ const char *inStr,
+ const char *postStr)
+{
+ TInfoSinkBase &out = objSink();
+ if (visit == PreVisit && preStr)
+ out << preStr;
+ else if (visit == InVisit && inStr)
+ out << inStr;
+ else if (visit == PostVisit && postStr)
+ out << postStr;
+}
+
+void TOutputGLSLBase::writeFunctionTriplet(Visit visit,
+ const ImmutableString &functionName,
+ bool useEmulatedFunction)
+{
+ TInfoSinkBase &out = objSink();
+ if (visit == PreVisit)
+ {
+ if (useEmulatedFunction)
+ {
+ BuiltInFunctionEmulator::WriteEmulatedFunctionName(out, functionName.data());
+ }
+ else
+ {
+ out << functionName;
+ }
+ out << "(";
+ }
+ else
+ {
+ writeTriplet(visit, nullptr, ", ", ")");
+ }
+}
+
+// Outputs what goes inside layout(), except for location and binding qualifiers, as they are
+// handled differently between GL GLSL and Vulkan GLSL.
+std::string TOutputGLSLBase::getCommonLayoutQualifiers(TIntermSymbol *variable)
+{
+ std::ostringstream out;
+ CommaSeparatedListItemPrefixGenerator listItemPrefix;
+
+ const TType &type = variable->getType();
+ const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
+
+ if (type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqFragmentInOut)
+ {
+ if (layoutQualifier.index >= 0)
+ {
+ out << listItemPrefix << "index = " << layoutQualifier.index;
+ }
+ if (layoutQualifier.yuv)
+ {
+ out << listItemPrefix << "yuv";
+ }
+ }
+
+ if (type.getQualifier() == EvqFragmentInOut && layoutQualifier.noncoherent)
+ {
+ out << listItemPrefix << "noncoherent";
+ }
+
+ if (IsImage(type.getBasicType()))
+ {
+ if (layoutQualifier.imageInternalFormat != EiifUnspecified)
+ {
+ ASSERT(type.getQualifier() == EvqTemporary || type.getQualifier() == EvqUniform);
+ out << listItemPrefix
+ << getImageInternalFormatString(layoutQualifier.imageInternalFormat);
+ }
+ }
+
+ if (IsAtomicCounter(type.getBasicType()))
+ {
+ out << listItemPrefix << "offset = " << layoutQualifier.offset;
+ }
+
+ return out.str();
+}
+
+// Outputs memory qualifiers applied to images, buffers and its fields, as well as image function
+// arguments.
+std::string TOutputGLSLBase::getMemoryQualifiers(const TType &type)
+{
+ std::ostringstream out;
+
+ const TMemoryQualifier &memoryQualifier = type.getMemoryQualifier();
+ if (memoryQualifier.readonly)
+ {
+ out << "readonly ";
+ }
+
+ if (memoryQualifier.writeonly)
+ {
+ out << "writeonly ";
+ }
+
+ if (memoryQualifier.coherent)
+ {
+ out << "coherent ";
+ }
+
+ if (memoryQualifier.restrictQualifier)
+ {
+ out << "restrict ";
+ }
+
+ if (memoryQualifier.volatileQualifier)
+ {
+ out << "volatile ";
+ }
+
+ return out.str();
+}
+
+void TOutputGLSLBase::writeLayoutQualifier(TIntermSymbol *variable)
+{
+ const TType &type = variable->getType();
+
+ if (!needsToWriteLayoutQualifier(type))
+ {
+ return;
+ }
+
+ if (type.getBasicType() == EbtInterfaceBlock)
+ {
+ declareInterfaceBlockLayout(type);
+ return;
+ }
+
+ TInfoSinkBase &out = objSink();
+ const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
+ out << "layout(";
+
+ CommaSeparatedListItemPrefixGenerator listItemPrefix;
+
+ if (IsFragmentOutput(type.getQualifier()) || type.getQualifier() == EvqVertexIn ||
+ IsVarying(type.getQualifier()))
+ {
+ if (layoutQualifier.location >= 0 ||
+ (mAlwaysSpecifyFragOutLocation && IsFragmentOutput(type.getQualifier())))
+ {
+ out << listItemPrefix << "location = " << std::max(layoutQualifier.location, 0);
+ }
+ }
+
+ if (IsOpaqueType(type.getBasicType()))
+ {
+ if (layoutQualifier.binding >= 0)
+ {
+ out << listItemPrefix << "binding = " << layoutQualifier.binding;
+ }
+ }
+
+ std::string otherQualifiers = getCommonLayoutQualifiers(variable);
+ if (!otherQualifiers.empty())
+ {
+ out << listItemPrefix << otherQualifiers;
+ }
+
+ out << ") ";
+}
+
+void TOutputGLSLBase::writeFieldLayoutQualifier(const TField *field)
+{
+ if (!field->type()->isMatrix() && !field->type()->isStructureContainingMatrices())
+ {
+ return;
+ }
+
+ TInfoSinkBase &out = objSink();
+
+ out << "layout(";
+ switch (field->type()->getLayoutQualifier().matrixPacking)
+ {
+ case EmpUnspecified:
+ case EmpColumnMajor:
+ // Default matrix packing is column major.
+ out << "column_major";
+ break;
+
+ case EmpRowMajor:
+ out << "row_major";
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ out << ") ";
+}
+
+void TOutputGLSLBase::writeQualifier(TQualifier qualifier, const TType &type, const TSymbol *symbol)
+{
+ const char *result = mapQualifierToString(qualifier);
+ if (result && result[0] != '\0')
+ {
+ objSink() << result << " ";
+ }
+
+ objSink() << getMemoryQualifiers(type);
+}
+
+const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier)
+{
+ if (sh::IsGLSL410OrOlder(mOutput) && mShaderVersion >= 300 &&
+ mCompileOptions.removeInvariantAndCentroidForESSL3)
+ {
+ switch (qualifier)
+ {
+ // The return string is consistent with sh::getQualifierString() from
+ // BaseTypes.h minus the "centroid" keyword.
+ case EvqCentroid:
+ return "";
+ case EvqCentroidIn:
+ return "smooth in";
+ case EvqCentroidOut:
+ return "smooth out";
+ default:
+ break;
+ }
+ }
+ if (sh::IsGLSL130OrNewer(mOutput))
+ {
+ switch (qualifier)
+ {
+ case EvqAttribute:
+ return "in";
+ case EvqVaryingIn:
+ return "in";
+ case EvqVaryingOut:
+ return "out";
+ default:
+ break;
+ }
+ }
+
+ switch (qualifier)
+ {
+ // gl_ClipDistance / gl_CullDistance require different qualifiers based on shader type.
+ case EvqClipDistance:
+ case EvqCullDistance:
+ return mShaderType == GL_FRAGMENT_SHADER ? "in" : "out";
+
+ // gl_LastFragColor / gl_LastFragData have no qualifiers.
+ case EvqLastFragData:
+ case EvqLastFragColor:
+ return nullptr;
+
+ default:
+ return sh::getQualifierString(qualifier);
+ }
+}
+
+namespace
+{
+
+constexpr char kIndent[] = " "; // 10x2 spaces
+constexpr int kIndentWidth = 2;
+constexpr int kMaxIndentLevel = sizeof(kIndent) / kIndentWidth;
+
+} // namespace
+
+const char *TOutputGLSLBase::getIndentPrefix(int extraIndentation)
+{
+ int indentDepth = std::min(kMaxIndentLevel, getCurrentBlockDepth() + extraIndentation);
+ ASSERT(indentDepth >= 0);
+ return kIndent + (kMaxIndentLevel - indentDepth) * kIndentWidth;
+}
+
+void TOutputGLSLBase::writeVariableType(const TType &type,
+ const TSymbol *symbol,
+ bool isFunctionArgument)
+{
+ TQualifier qualifier = type.getQualifier();
+ TInfoSinkBase &out = objSink();
+ if (type.isInvariant())
+ {
+ writeInvariantQualifier(type);
+ }
+ if (type.isPrecise())
+ {
+ writePreciseQualifier(type);
+ }
+ if (qualifier != EvqTemporary && qualifier != EvqGlobal)
+ {
+ writeQualifier(qualifier, type, symbol);
+ }
+ if (isFunctionArgument)
+ {
+ // Function arguments are the only place (other than image/SSBO/field declaration) where
+ // memory qualifiers can appear.
+ out << getMemoryQualifiers(type);
+ }
+
+ // Declare the struct.
+ if (type.isStructSpecifier())
+ {
+ const TStructure *structure = type.getStruct();
+
+ declareStruct(structure);
+ }
+ else if (type.getBasicType() == EbtInterfaceBlock)
+ {
+ declareInterfaceBlock(type);
+ }
+ else
+ {
+ if (writeVariablePrecision(type.getPrecision()))
+ out << " ";
+ out << getTypeName(type);
+ }
+}
+
+void TOutputGLSLBase::writeFunctionParameters(const TFunction *func)
+{
+ TInfoSinkBase &out = objSink();
+ size_t paramCount = func->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ const TVariable *param = func->getParam(i);
+ const TType &type = param->getType();
+ writeVariableType(type, param, true);
+
+ if (param->symbolType() != SymbolType::Empty)
+ {
+ out << " " << hashName(param);
+ }
+ if (type.isArray())
+ {
+ out << ArrayString(type);
+ }
+
+ // Put a comma if this is not the last argument.
+ if (i != paramCount - 1)
+ out << ", ";
+ }
+}
+
+const TConstantUnion *TOutputGLSLBase::writeConstantUnion(const TType &type,
+ const TConstantUnion *pConstUnion)
+{
+ TInfoSinkBase &out = objSink();
+
+ if (type.getBasicType() == EbtStruct)
+ {
+ const TStructure *structure = type.getStruct();
+ out << hashName(structure) << "(";
+
+ const TFieldList &fields = structure->fields();
+ for (size_t i = 0; i < fields.size(); ++i)
+ {
+ const TType *fieldType = fields[i]->type();
+ ASSERT(fieldType != nullptr);
+ pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
+ if (i != fields.size() - 1)
+ out << ", ";
+ }
+ out << ")";
+ }
+ else
+ {
+ size_t size = type.getObjectSize();
+ bool writeType = size > 1;
+ if (writeType)
+ out << getTypeName(type) << "(";
+ for (size_t i = 0; i < size; ++i, ++pConstUnion)
+ {
+ switch (pConstUnion->getType())
+ {
+ case EbtFloat:
+ writeFloat(out, pConstUnion->getFConst());
+ break;
+ case EbtInt:
+ out << pConstUnion->getIConst();
+ break;
+ case EbtUInt:
+ out << pConstUnion->getUConst() << "u";
+ break;
+ case EbtBool:
+ out << pConstUnion->getBConst();
+ break;
+ case EbtYuvCscStandardEXT:
+ out << getYuvCscStandardEXTString(pConstUnion->getYuvCscStandardEXTConst());
+ break;
+ default:
+ UNREACHABLE();
+ }
+ if (i != size - 1)
+ out << ", ";
+ }
+ if (writeType)
+ out << ")";
+ }
+ return pConstUnion;
+}
+
+void TOutputGLSLBase::writeConstructorTriplet(Visit visit, const TType &type)
+{
+ TInfoSinkBase &out = objSink();
+ if (visit == PreVisit)
+ {
+ if (type.isArray())
+ {
+ out << getTypeName(type);
+ out << ArrayString(type);
+ out << "(";
+ }
+ else
+ {
+ out << getTypeName(type) << "(";
+ }
+ }
+ else
+ {
+ writeTriplet(visit, nullptr, ", ", ")");
+ }
+}
+
+void TOutputGLSLBase::visitSymbol(TIntermSymbol *node)
+{
+ TInfoSinkBase &out = objSink();
+ out << hashName(&node->variable());
+
+ if (mDeclaringVariable && node->getType().isArray())
+ out << ArrayString(node->getType());
+}
+
+void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion *node)
+{
+ writeConstantUnion(node->getType(), node->getConstantValue());
+}
+
+bool TOutputGLSLBase::visitSwizzle(Visit visit, TIntermSwizzle *node)
+{
+ TInfoSinkBase &out = objSink();
+ if (visit == PostVisit)
+ {
+ out << ".";
+ node->writeOffsetsAsXYZW(&out);
+ }
+ return true;
+}
+
+bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
+{
+ bool visitChildren = true;
+ TInfoSinkBase &out = objSink();
+ switch (node->getOp())
+ {
+ case EOpComma:
+ writeTriplet(visit, "(", ", ", ")");
+ break;
+ case EOpInitialize:
+ if (visit == InVisit)
+ {
+ out << " = ";
+ // RHS of initialize is not being declared.
+ mDeclaringVariable = false;
+ }
+ break;
+ case EOpAssign:
+ writeTriplet(visit, "(", " = ", ")");
+ break;
+ case EOpAddAssign:
+ writeTriplet(visit, "(", " += ", ")");
+ break;
+ case EOpSubAssign:
+ writeTriplet(visit, "(", " -= ", ")");
+ break;
+ case EOpDivAssign:
+ writeTriplet(visit, "(", " /= ", ")");
+ break;
+ case EOpIModAssign:
+ writeTriplet(visit, "(", " %= ", ")");
+ break;
+ // Notice the fall-through.
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+ writeTriplet(visit, "(", " *= ", ")");
+ break;
+ case EOpBitShiftLeftAssign:
+ writeTriplet(visit, "(", " <<= ", ")");
+ break;
+ case EOpBitShiftRightAssign:
+ writeTriplet(visit, "(", " >>= ", ")");
+ break;
+ case EOpBitwiseAndAssign:
+ writeTriplet(visit, "(", " &= ", ")");
+ break;
+ case EOpBitwiseXorAssign:
+ writeTriplet(visit, "(", " ^= ", ")");
+ break;
+ case EOpBitwiseOrAssign:
+ writeTriplet(visit, "(", " |= ", ")");
+ break;
+
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ writeTriplet(visit, nullptr, "[", "]");
+ break;
+ case EOpIndexDirectStruct:
+ if (visit == InVisit)
+ {
+ // Here we are writing out "foo.bar", where "foo" is struct
+ // and "bar" is field. In AST, it is represented as a binary
+ // node, where left child represents "foo" and right child "bar".
+ // The node itself represents ".". The struct field "bar" is
+ // actually stored as an index into TStructure::fields.
+ out << ".";
+ const TStructure *structure = node->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+
+ out << hashFieldName(field);
+ visitChildren = false;
+ }
+ break;
+ case EOpIndexDirectInterfaceBlock:
+ if (visit == InVisit)
+ {
+ out << ".";
+ const TInterfaceBlock *interfaceBlock =
+ node->getLeft()->getType().getInterfaceBlock();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = interfaceBlock->fields()[index->getIConst(0)];
+ out << hashFieldName(field);
+ visitChildren = false;
+ }
+ break;
+
+ case EOpAdd:
+ writeTriplet(visit, "(", " + ", ")");
+ break;
+ case EOpSub:
+ writeTriplet(visit, "(", " - ", ")");
+ break;
+ case EOpMul:
+ writeTriplet(visit, "(", " * ", ")");
+ break;
+ case EOpDiv:
+ writeTriplet(visit, "(", " / ", ")");
+ break;
+ case EOpIMod:
+ writeTriplet(visit, "(", " % ", ")");
+ break;
+ case EOpBitShiftLeft:
+ writeTriplet(visit, "(", " << ", ")");
+ break;
+ case EOpBitShiftRight:
+ writeTriplet(visit, "(", " >> ", ")");
+ break;
+ case EOpBitwiseAnd:
+ writeTriplet(visit, "(", " & ", ")");
+ break;
+ case EOpBitwiseXor:
+ writeTriplet(visit, "(", " ^ ", ")");
+ break;
+ case EOpBitwiseOr:
+ writeTriplet(visit, "(", " | ", ")");
+ break;
+
+ case EOpEqual:
+ writeTriplet(visit, "(", " == ", ")");
+ break;
+ case EOpNotEqual:
+ writeTriplet(visit, "(", " != ", ")");
+ break;
+ case EOpLessThan:
+ writeTriplet(visit, "(", " < ", ")");
+ break;
+ case EOpGreaterThan:
+ writeTriplet(visit, "(", " > ", ")");
+ break;
+ case EOpLessThanEqual:
+ writeTriplet(visit, "(", " <= ", ")");
+ break;
+ case EOpGreaterThanEqual:
+ writeTriplet(visit, "(", " >= ", ")");
+ break;
+
+ // Notice the fall-through.
+ case EOpVectorTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpMatrixTimesMatrix:
+ writeTriplet(visit, "(", " * ", ")");
+ break;
+
+ case EOpLogicalOr:
+ writeTriplet(visit, "(", " || ", ")");
+ break;
+ case EOpLogicalXor:
+ writeTriplet(visit, "(", " ^^ ", ")");
+ break;
+ case EOpLogicalAnd:
+ writeTriplet(visit, "(", " && ", ")");
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return visitChildren;
+}
+
+bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
+{
+ const char *preString = "";
+ const char *postString = ")";
+
+ switch (node->getOp())
+ {
+ case EOpNegative:
+ preString = "(-";
+ break;
+ case EOpPositive:
+ preString = "(+";
+ break;
+ case EOpLogicalNot:
+ preString = "(!";
+ break;
+ case EOpBitwiseNot:
+ preString = "(~";
+ break;
+
+ case EOpPostIncrement:
+ preString = "(";
+ postString = "++)";
+ break;
+ case EOpPostDecrement:
+ preString = "(";
+ postString = "--)";
+ break;
+ case EOpPreIncrement:
+ preString = "(++";
+ break;
+ case EOpPreDecrement:
+ preString = "(--";
+ break;
+ case EOpArrayLength:
+ preString = "((";
+ postString = ").length())";
+ break;
+
+ default:
+ writeFunctionTriplet(visit, node->getFunction()->name(),
+ node->getUseEmulatedFunction());
+ return true;
+ }
+
+ writeTriplet(visit, preString, nullptr, postString);
+
+ return true;
+}
+
+bool TOutputGLSLBase::visitTernary(Visit visit, TIntermTernary *node)
+{
+ TInfoSinkBase &out = objSink();
+ // Notice two brackets at the beginning and end. The outer ones
+ // encapsulate the whole ternary expression. This preserves the
+ // order of precedence when ternary expressions are used in a
+ // compound expression, i.e., c = 2 * (a < b ? 1 : 2).
+ out << "((";
+ node->getCondition()->traverse(this);
+ out << ") ? (";
+ node->getTrueExpression()->traverse(this);
+ out << ") : (";
+ node->getFalseExpression()->traverse(this);
+ out << "))";
+ return false;
+}
+
+bool TOutputGLSLBase::visitIfElse(Visit visit, TIntermIfElse *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ out << "if (";
+ node->getCondition()->traverse(this);
+ out << ")\n";
+
+ visitCodeBlock(node->getTrueBlock());
+
+ if (node->getFalseBlock())
+ {
+ out << getIndentPrefix() << "else\n";
+ visitCodeBlock(node->getFalseBlock());
+ }
+ return false;
+}
+
+bool TOutputGLSLBase::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ ASSERT(node->getStatementList());
+ writeTriplet(visit, "switch (", ") ", nullptr);
+ // The curly braces get written when visiting the statementList aggregate
+ return true;
+}
+
+bool TOutputGLSLBase::visitCase(Visit visit, TIntermCase *node)
+{
+ if (node->hasCondition())
+ {
+ writeTriplet(visit, "case (", nullptr, "):\n");
+ return true;
+ }
+ else
+ {
+ TInfoSinkBase &out = objSink();
+ out << "default:\n";
+ return false;
+ }
+}
+
+bool TOutputGLSLBase::visitBlock(Visit visit, TIntermBlock *node)
+{
+ TInfoSinkBase &out = objSink();
+ // Scope the blocks except when at the global scope.
+ if (getCurrentTraversalDepth() > 0)
+ {
+ out << "{\n";
+ }
+
+ for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
+ iter != node->getSequence()->end(); ++iter)
+ {
+ TIntermNode *curNode = *iter;
+ ASSERT(curNode != nullptr);
+
+ out << getIndentPrefix(curNode->getAsCaseNode() ? -1 : 0);
+
+ curNode->traverse(this);
+
+ if (isSingleStatement(curNode))
+ out << ";\n";
+ }
+
+ // Scope the blocks except when at the global scope.
+ if (getCurrentTraversalDepth() > 0)
+ {
+ out << getIndentPrefix(-1) << "}\n";
+ }
+ return false;
+}
+
+bool TOutputGLSLBase::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+{
+ TIntermFunctionPrototype *prototype = node->getFunctionPrototype();
+ prototype->traverse(this);
+ visitCodeBlock(node->getBody());
+
+ // Fully processed; no need to visit children.
+ return false;
+}
+
+bool TOutputGLSLBase::visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+{
+ TInfoSinkBase &out = objSink();
+ ASSERT(visit == PreVisit);
+ const TIntermSymbol *symbol = node->getSymbol();
+ out << (node->isPrecise() ? "precise " : "invariant ") << hashName(&symbol->variable());
+ return false;
+}
+
+void TOutputGLSLBase::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ const TType &type = node->getType();
+ writeVariableType(type, node->getFunction(), false);
+ if (type.isArray())
+ out << ArrayString(type);
+
+ out << " " << hashFunctionNameIfNeeded(node->getFunction());
+
+ out << "(";
+ writeFunctionParameters(node->getFunction());
+ out << ")";
+}
+
+bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ bool visitChildren = true;
+ if (node->getOp() == EOpConstruct)
+ {
+ writeConstructorTriplet(visit, node->getType());
+ }
+ else
+ {
+ // Function call.
+ ImmutableString functionName = node->getFunction()->name();
+ if (visit == PreVisit)
+ {
+ // No raw function is expected.
+ ASSERT(node->getOp() != EOpCallInternalRawFunction);
+
+ if (node->getOp() == EOpCallFunctionInAST)
+ {
+ functionName = hashFunctionNameIfNeeded(node->getFunction());
+ }
+ else
+ {
+ functionName =
+ translateTextureFunction(node->getFunction()->name(), mCompileOptions);
+ }
+ }
+ writeFunctionTriplet(visit, functionName, node->getUseEmulatedFunction());
+ }
+ return visitChildren;
+}
+
+bool TOutputGLSLBase::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ // Variable declaration.
+ if (visit == PreVisit)
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ TIntermTyped *decl = sequence.front()->getAsTyped();
+ TIntermSymbol *symbolNode = decl->getAsSymbolNode();
+ if (symbolNode == nullptr)
+ {
+ ASSERT(decl->getAsBinaryNode() && decl->getAsBinaryNode()->getOp() == EOpInitialize);
+ symbolNode = decl->getAsBinaryNode()->getLeft()->getAsSymbolNode();
+ }
+ ASSERT(symbolNode);
+
+ if (symbolNode->getName() != "gl_ClipDistance" &&
+ symbolNode->getName() != "gl_CullDistance")
+ {
+ // gl_Clip/CullDistance re-declaration doesn't need layout.
+ writeLayoutQualifier(symbolNode);
+ }
+
+ writeVariableType(symbolNode->getType(), &symbolNode->variable(), false);
+ if (symbolNode->variable().symbolType() != SymbolType::Empty)
+ {
+ out << " ";
+ }
+ mDeclaringVariable = true;
+ }
+ else if (visit == InVisit)
+ {
+ UNREACHABLE();
+ }
+ else
+ {
+ mDeclaringVariable = false;
+ }
+ return true;
+}
+
+bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ TLoopType loopType = node->getType();
+
+ if (loopType == ELoopFor) // for loop
+ {
+ out << "for (";
+ if (node->getInit())
+ node->getInit()->traverse(this);
+ out << "; ";
+
+ if (node->getCondition())
+ node->getCondition()->traverse(this);
+ out << "; ";
+
+ if (node->getExpression())
+ node->getExpression()->traverse(this);
+ out << ")\n";
+
+ visitCodeBlock(node->getBody());
+ }
+ else if (loopType == ELoopWhile) // while loop
+ {
+ out << "while (";
+ ASSERT(node->getCondition() != nullptr);
+ node->getCondition()->traverse(this);
+ out << ")\n";
+
+ visitCodeBlock(node->getBody());
+ }
+ else // do-while loop
+ {
+ ASSERT(loopType == ELoopDoWhile);
+ out << "do\n";
+
+ visitCodeBlock(node->getBody());
+
+ out << "while (";
+ ASSERT(node->getCondition() != nullptr);
+ node->getCondition()->traverse(this);
+ out << ");\n";
+ }
+
+ // No need to visit children. They have been already processed in
+ // this function.
+ return false;
+}
+
+bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch *node)
+{
+ switch (node->getFlowOp())
+ {
+ case EOpKill:
+ writeTriplet(visit, "discard", nullptr, nullptr);
+ break;
+ case EOpBreak:
+ writeTriplet(visit, "break", nullptr, nullptr);
+ break;
+ case EOpContinue:
+ writeTriplet(visit, "continue", nullptr, nullptr);
+ break;
+ case EOpReturn:
+ writeTriplet(visit, "return ", nullptr, nullptr);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return true;
+}
+
+void TOutputGLSLBase::visitCodeBlock(TIntermBlock *node)
+{
+ TInfoSinkBase &out = objSink();
+ if (node != nullptr)
+ {
+ out << getIndentPrefix();
+ node->traverse(this);
+ // Single statements not part of a sequence need to be terminated
+ // with semi-colon.
+ if (isSingleStatement(node))
+ out << ";\n";
+ }
+ else
+ {
+ out << "{\n}\n"; // Empty code block.
+ }
+}
+
+void TOutputGLSLBase::visitPreprocessorDirective(TIntermPreprocessorDirective *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ out << "\n";
+
+ switch (node->getDirective())
+ {
+ case PreprocessorDirective::Define:
+ out << "#define";
+ break;
+ case PreprocessorDirective::Endif:
+ out << "#endif";
+ break;
+ case PreprocessorDirective::If:
+ out << "#if";
+ break;
+ case PreprocessorDirective::Ifdef:
+ out << "#ifdef";
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (!node->getCommand().empty())
+ {
+ out << " " << node->getCommand();
+ }
+
+ out << "\n";
+}
+
+ImmutableString TOutputGLSLBase::getTypeName(const TType &type)
+{
+ if (type.getBasicType() == EbtSamplerVideoWEBGL)
+ {
+ // TODO(http://anglebug.com/3889): translate SamplerVideoWEBGL into different token
+ // when necessary (e.g. on Android devices)
+ return ImmutableString("sampler2D");
+ }
+
+ return GetTypeName(type, mHashFunction, &mNameMap);
+}
+
+ImmutableString TOutputGLSLBase::hashName(const TSymbol *symbol)
+{
+ return HashName(symbol, mHashFunction, &mNameMap);
+}
+
+ImmutableString TOutputGLSLBase::hashFieldName(const TField *field)
+{
+ ASSERT(field->symbolType() != SymbolType::Empty);
+ if (field->symbolType() == SymbolType::UserDefined)
+ {
+ return HashName(field->name(), mHashFunction, &mNameMap);
+ }
+
+ return field->name();
+}
+
+ImmutableString TOutputGLSLBase::hashFunctionNameIfNeeded(const TFunction *func)
+{
+ if (func->isMain())
+ {
+ return func->name();
+ }
+ else
+ {
+ return hashName(func);
+ }
+}
+
+void TOutputGLSLBase::declareStruct(const TStructure *structure)
+{
+ TInfoSinkBase &out = objSink();
+
+ out << "struct ";
+
+ if (structure->symbolType() != SymbolType::Empty)
+ {
+ out << hashName(structure) << " ";
+ }
+ out << "{\n";
+ const TFieldList &fields = structure->fields();
+ for (size_t i = 0; i < fields.size(); ++i)
+ {
+ out << getIndentPrefix(1);
+ const TField *field = fields[i];
+ const TType &fieldType = *field->type();
+ if (writeVariablePrecision(fieldType.getPrecision()))
+ {
+ out << " ";
+ }
+ if (fieldType.isPrecise())
+ {
+ writePreciseQualifier(fieldType);
+ }
+ out << getTypeName(fieldType) << " " << hashFieldName(field);
+ if (fieldType.isArray())
+ {
+ out << ArrayString(fieldType);
+ }
+ out << ";\n";
+ }
+ out << getIndentPrefix() << "}";
+}
+
+void TOutputGLSLBase::declareInterfaceBlockLayout(const TType &type)
+{
+ // 4.4.5 Uniform and Shader Storage Block Layout Qualifiers in GLSL 4.5 spec.
+ // Layout qualifiers can be used for uniform and shader storage blocks,
+ // but not for non-block uniform declarations.
+ if (IsShaderIoBlock(type.getQualifier()))
+ {
+ return;
+ }
+
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ TInfoSinkBase &out = objSink();
+
+ out << "layout(";
+
+ switch (interfaceBlock->blockStorage())
+ {
+ case EbsUnspecified:
+ case EbsShared:
+ // Default block storage is shared.
+ out << "shared";
+ break;
+
+ case EbsPacked:
+ out << "packed";
+ break;
+
+ case EbsStd140:
+ out << "std140";
+ break;
+
+ case EbsStd430:
+ out << "std430";
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (interfaceBlock->blockBinding() >= 0)
+ {
+ out << ", ";
+ out << "binding = " << interfaceBlock->blockBinding();
+ }
+
+ out << ") ";
+}
+
+const char *getVariableInterpolation(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqSmoothOut:
+ return "smooth out ";
+ case EvqFlatOut:
+ return "flat out ";
+ case EvqNoPerspectiveOut:
+ return "noperspective out ";
+ case EvqCentroidOut:
+ return "centroid out ";
+ case EvqSmoothIn:
+ return "smooth in ";
+ case EvqFlatIn:
+ return "flat in ";
+ case EvqNoPerspectiveIn:
+ return "noperspective in ";
+ case EvqCentroidIn:
+ return "centroid in ";
+ default:
+ break;
+ }
+ return nullptr;
+}
+
+void TOutputGLSLBase::declareInterfaceBlock(const TType &type)
+{
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ TInfoSinkBase &out = objSink();
+
+ out << hashName(interfaceBlock) << "{\n";
+ const TFieldList &fields = interfaceBlock->fields();
+ for (const TField *field : fields)
+ {
+ out << getIndentPrefix(1);
+ if (!IsShaderIoBlock(type.getQualifier()) && type.getQualifier() != EvqPatchIn &&
+ type.getQualifier() != EvqPatchOut)
+ {
+ writeFieldLayoutQualifier(field);
+ }
+
+ const TType &fieldType = *field->type();
+
+ out << getMemoryQualifiers(fieldType);
+ if (writeVariablePrecision(fieldType.getPrecision()))
+ out << " ";
+ if (fieldType.isInvariant())
+ {
+ writeInvariantQualifier(fieldType);
+ }
+ if (fieldType.isPrecise())
+ {
+ writePreciseQualifier(fieldType);
+ }
+
+ const char *qualifier = getVariableInterpolation(fieldType.getQualifier());
+ if (qualifier != nullptr)
+ out << qualifier;
+
+ out << getTypeName(fieldType) << " " << hashFieldName(field);
+
+ if (fieldType.isArray())
+ out << ArrayString(fieldType);
+ out << ";\n";
+ }
+ out << "}";
+}
+
+void WritePragma(TInfoSinkBase &out, const ShCompileOptions &compileOptions, const TPragma &pragma)
+{
+ if (!compileOptions.flattenPragmaSTDGLInvariantAll)
+ {
+ if (pragma.stdgl.invariantAll)
+ out << "#pragma STDGL invariant(all)\n";
+ }
+}
+
+void WriteGeometryShaderLayoutQualifiers(TInfoSinkBase &out,
+ sh::TLayoutPrimitiveType inputPrimitive,
+ int invocations,
+ sh::TLayoutPrimitiveType outputPrimitive,
+ int maxVertices)
+{
+ // Omit 'invocations = 1'
+ if (inputPrimitive != EptUndefined || invocations > 1)
+ {
+ out << "layout (";
+
+ if (inputPrimitive != EptUndefined)
+ {
+ out << getGeometryShaderPrimitiveTypeString(inputPrimitive);
+ }
+
+ if (invocations > 1)
+ {
+ if (inputPrimitive != EptUndefined)
+ {
+ out << ", ";
+ }
+ out << "invocations = " << invocations;
+ }
+ out << ") in;\n";
+ }
+
+ if (outputPrimitive != EptUndefined || maxVertices != -1)
+ {
+ out << "layout (";
+
+ if (outputPrimitive != EptUndefined)
+ {
+ out << getGeometryShaderPrimitiveTypeString(outputPrimitive);
+ }
+
+ if (maxVertices != -1)
+ {
+ if (outputPrimitive != EptUndefined)
+ {
+ out << ", ";
+ }
+ out << "max_vertices = " << maxVertices;
+ }
+ out << ") out;\n";
+ }
+}
+
+void WriteTessControlShaderLayoutQualifiers(TInfoSinkBase &out, int inputVertices)
+{
+ if (inputVertices != 0)
+ {
+ out << "layout (vertices = " << inputVertices << ") out;\n";
+ }
+}
+
+void WriteTessEvaluationShaderLayoutQualifiers(TInfoSinkBase &out,
+ sh::TLayoutTessEvaluationType inputPrimitive,
+ sh::TLayoutTessEvaluationType inputVertexSpacing,
+ sh::TLayoutTessEvaluationType inputOrdering,
+ sh::TLayoutTessEvaluationType inputPoint)
+{
+ if (inputPrimitive != EtetUndefined)
+ {
+ out << "layout (";
+ out << getTessEvaluationShaderTypeString(inputPrimitive);
+ if (inputVertexSpacing != EtetUndefined)
+ {
+ out << ", " << getTessEvaluationShaderTypeString(inputVertexSpacing);
+ }
+ if (inputOrdering != EtetUndefined)
+ {
+ out << ", " << getTessEvaluationShaderTypeString(inputOrdering);
+ }
+ if (inputPoint != EtetUndefined)
+ {
+ out << ", " << getTessEvaluationShaderTypeString(inputPoint);
+ }
+ out << ") in;\n";
+ }
+}
+
+// If SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS is enabled, layout qualifiers are spilled whenever
+// variables with specified layout qualifiers are copied. Additional checks are needed against the
+// type and storage qualifier of the variable to verify that layout qualifiers have to be outputted.
+// TODO (mradev): Fix layout qualifier spilling in ScalarizeVecAndMatConstructorArgs and remove
+// NeedsToWriteLayoutQualifier.
+bool TOutputGLSLBase::needsToWriteLayoutQualifier(const TType &type)
+{
+ if (type.getBasicType() == EbtInterfaceBlock)
+ {
+ return true;
+ }
+
+ const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
+
+ if (IsFragmentOutput(type.getQualifier()) || type.getQualifier() == EvqVertexIn ||
+ IsVarying(type.getQualifier()))
+ {
+ if (layoutQualifier.location >= 0 ||
+ (mAlwaysSpecifyFragOutLocation && IsFragmentOutput(type.getQualifier())))
+ {
+ return true;
+ }
+ }
+
+ if (type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqFragmentInOut)
+ {
+ if (layoutQualifier.index >= 0)
+ {
+ return true;
+ }
+ if (layoutQualifier.yuv)
+ {
+ return true;
+ }
+ }
+
+ if (type.getQualifier() == EvqFragmentInOut && layoutQualifier.noncoherent)
+ {
+ return true;
+ }
+
+ if (IsOpaqueType(type.getBasicType()) && layoutQualifier.binding != -1)
+ {
+ return true;
+ }
+
+ if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified)
+ {
+ return true;
+ }
+ return false;
+}
+
+void EmitEarlyFragmentTestsGLSL(const TCompiler &compiler, TInfoSinkBase &sink)
+{
+ if (compiler.isEarlyFragmentTestsSpecified())
+ {
+ sink << "layout (early_fragment_tests) in;\n";
+ }
+}
+
+void EmitWorkGroupSizeGLSL(const TCompiler &compiler, TInfoSinkBase &sink)
+{
+ if (compiler.isComputeShaderLocalSizeDeclared())
+ {
+ const sh::WorkGroupSize &localSize = compiler.getComputeShaderLocalSize();
+ sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1]
+ << ", local_size_z=" << localSize[2] << ") in;\n";
+ }
+}
+
+void EmitMultiviewGLSL(const TCompiler &compiler,
+ const ShCompileOptions &compileOptions,
+ const TExtension extension,
+ const TBehavior behavior,
+ TInfoSinkBase &sink)
+{
+ ASSERT(behavior != EBhUndefined);
+ if (behavior == EBhDisable)
+ return;
+
+ const bool isVertexShader = (compiler.getShaderType() == GL_VERTEX_SHADER);
+ if (compileOptions.initializeBuiltinsForInstancedMultiview)
+ {
+ // Emit ARB_shader_viewport_layer_array/NV_viewport_array2 in a vertex shader if the
+ // SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set and the
+ // OVR_multiview(2) extension is requested.
+ if (isVertexShader && compileOptions.selectViewInNvGLSLVertexShader)
+ {
+ sink << "#if defined(GL_ARB_shader_viewport_layer_array)\n"
+ << "#extension GL_ARB_shader_viewport_layer_array : require\n"
+ << "#elif defined(GL_NV_viewport_array2)\n"
+ << "#extension GL_NV_viewport_array2 : require\n"
+ << "#endif\n";
+ }
+ }
+ else
+ {
+ sink << "#extension GL_OVR_multiview";
+ if (extension == TExtension::OVR_multiview2)
+ {
+ sink << "2";
+ }
+ sink << " : " << GetBehaviorString(behavior) << "\n";
+
+ const auto &numViews = compiler.getNumViews();
+ if (isVertexShader && numViews != -1)
+ {
+ sink << "layout(num_views=" << numViews << ") in;\n";
+ }
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h b/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h
new file mode 100644
index 0000000000..5552eb606f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h
@@ -0,0 +1,154 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
+#define COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
+
+#include <set>
+
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/HashNames.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Pragma.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+class TCompiler;
+
+class TOutputGLSLBase : public TIntermTraverser
+{
+ public:
+ TOutputGLSLBase(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions);
+
+ ShShaderOutput getShaderOutput() const { return mOutput; }
+
+ // Return the original name if hash function pointer is NULL;
+ // otherwise return the hashed name. Has special handling for internal names and built-ins,
+ // which are not hashed.
+ ImmutableString hashName(const TSymbol *symbol);
+
+ protected:
+ TInfoSinkBase &objSink() { return mObjSink; }
+ void writeFloat(TInfoSinkBase &out, float f);
+ void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
+ std::string getCommonLayoutQualifiers(TIntermSymbol *variable);
+ std::string getMemoryQualifiers(const TType &type);
+ virtual void writeLayoutQualifier(TIntermSymbol *variable);
+ void writeFieldLayoutQualifier(const TField *field);
+ void writeInvariantQualifier(const TType &type);
+ void writePreciseQualifier(const TType &type);
+ virtual void writeVariableType(const TType &type,
+ const TSymbol *symbol,
+ bool isFunctionArgument);
+ virtual bool writeVariablePrecision(TPrecision precision) = 0;
+ void writeFunctionParameters(const TFunction *func);
+ const TConstantUnion *writeConstantUnion(const TType &type, const TConstantUnion *pConstUnion);
+ void writeConstructorTriplet(Visit visit, const TType &type);
+ ImmutableString getTypeName(const TType &type);
+
+ void visitSymbol(TIntermSymbol *node) override;
+ void visitConstantUnion(TIntermConstantUnion *node) override;
+ bool visitSwizzle(Visit visit, TIntermSwizzle *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+ bool visitTernary(Visit visit, TIntermTernary *node) override;
+ bool visitIfElse(Visit visit, TIntermIfElse *node) override;
+ bool visitSwitch(Visit visit, TIntermSwitch *node) override;
+ bool visitCase(Visit visit, TIntermCase *node) override;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitLoop(Visit visit, TIntermLoop *node) override;
+ bool visitBranch(Visit visit, TIntermBranch *node) override;
+ void visitPreprocessorDirective(TIntermPreprocessorDirective *node) override;
+
+ void visitCodeBlock(TIntermBlock *node);
+
+ ImmutableString hashFieldName(const TField *field);
+ // Same as hashName(), but without hashing "main".
+ ImmutableString hashFunctionNameIfNeeded(const TFunction *func);
+ // Used to translate function names for differences between ESSL and GLSL
+ virtual ImmutableString translateTextureFunction(const ImmutableString &name,
+ const ShCompileOptions &option)
+ {
+ return name;
+ }
+
+ void declareStruct(const TStructure *structure);
+ void writeQualifier(TQualifier qualifier, const TType &type, const TSymbol *symbol);
+
+ const char *mapQualifierToString(TQualifier qualifier);
+
+ sh::GLenum getShaderType() const { return mShaderType; }
+ bool isHighPrecisionSupported() const { return mHighPrecisionSupported; }
+ const char *getIndentPrefix(int extraIndentDepth = 0);
+
+ bool needsToWriteLayoutQualifier(const TType &type);
+
+ private:
+ void declareInterfaceBlockLayout(const TType &type);
+ void declareInterfaceBlock(const TType &type);
+
+ void writeFunctionTriplet(Visit visit,
+ const ImmutableString &functionName,
+ bool useEmulatedFunction);
+
+ TInfoSinkBase &mObjSink;
+ bool mDeclaringVariable;
+
+ // name hashing.
+ ShHashFunction64 mHashFunction;
+ NameMap &mNameMap;
+
+ sh::GLenum mShaderType;
+ const int mShaderVersion;
+ ShShaderOutput mOutput;
+
+ bool mHighPrecisionSupported;
+
+ // Emit "layout(locaton = 0)" for fragment outputs whose location is unspecified. This is for
+ // transformations like pixel local storage, where new outputs are introduced to the shader, and
+ // previously valid fragment outputs with an implicit location of 0 are now required to specify
+ // their location.
+ bool mAlwaysSpecifyFragOutLocation;
+
+ const ShCompileOptions &mCompileOptions;
+};
+
+void WritePragma(TInfoSinkBase &out, const ShCompileOptions &compileOptions, const TPragma &pragma);
+
+void WriteGeometryShaderLayoutQualifiers(TInfoSinkBase &out,
+ sh::TLayoutPrimitiveType inputPrimitive,
+ int invocations,
+ sh::TLayoutPrimitiveType outputPrimitive,
+ int maxVertices);
+
+void WriteTessControlShaderLayoutQualifiers(TInfoSinkBase &out, int inputVertices);
+
+void WriteTessEvaluationShaderLayoutQualifiers(TInfoSinkBase &out,
+ sh::TLayoutTessEvaluationType inputPrimitive,
+ sh::TLayoutTessEvaluationType inputVertexSpacing,
+ sh::TLayoutTessEvaluationType inputOrdering,
+ sh::TLayoutTessEvaluationType inputPoint);
+
+void EmitEarlyFragmentTestsGLSL(const TCompiler &, TInfoSinkBase &sink);
+void EmitWorkGroupSizeGLSL(const TCompiler &, TInfoSinkBase &sink);
+void EmitMultiviewGLSL(const TCompiler &,
+ const ShCompileOptions &,
+ const TExtension,
+ const TBehavior,
+ TInfoSinkBase &sink);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp
new file mode 100644
index 0000000000..12f220b448
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp
@@ -0,0 +1,3700 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/OutputHLSL.h"
+
+#include <stdio.h>
+#include <algorithm>
+#include <cfloat>
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "compiler/translator/AtomicCounterFunctionHLSL.h"
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
+#include "compiler/translator/ImageFunctionHLSL.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/ResourcesHLSL.h"
+#include "compiler/translator/StructureHLSL.h"
+#include "compiler/translator/TextureFunctionHLSL.h"
+#include "compiler/translator/TranslatorHLSL.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/blocklayout.h"
+#include "compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h"
+#include "compiler/translator/tree_util/FindSymbolNode.h"
+#include "compiler/translator/tree_util/NodeSearch.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const char kImage2DFunctionString[] = "// @@ IMAGE2D DECLARATION FUNCTION STRING @@";
+
+TString ArrayHelperFunctionName(const char *prefix, const TType &type)
+{
+ TStringStream fnName = sh::InitializeStream<TStringStream>();
+ fnName << prefix << "_";
+ if (type.isArray())
+ {
+ for (unsigned int arraySize : type.getArraySizes())
+ {
+ fnName << arraySize << "_";
+ }
+ }
+ fnName << TypeString(type);
+ return fnName.str();
+}
+
+bool IsDeclarationWrittenOut(TIntermDeclaration *node)
+{
+ TIntermSequence *sequence = node->getSequence();
+ TIntermTyped *variable = (*sequence)[0]->getAsTyped();
+ ASSERT(sequence->size() == 1);
+ ASSERT(variable);
+ return (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal ||
+ variable->getQualifier() == EvqConst || variable->getQualifier() == EvqShared);
+}
+
+bool IsInStd140UniformBlock(TIntermTyped *node)
+{
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+
+ if (binaryNode)
+ {
+ return IsInStd140UniformBlock(binaryNode->getLeft());
+ }
+
+ const TType &type = node->getType();
+
+ if (type.getQualifier() == EvqUniform)
+ {
+ // determine if we are in the standard layout
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ if (interfaceBlock)
+ {
+ return (interfaceBlock->blockStorage() == EbsStd140);
+ }
+ }
+
+ return false;
+}
+
+const TInterfaceBlock *GetInterfaceBlockOfUniformBlockNearestIndexOperator(TIntermTyped *node)
+{
+ const TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
+ {
+ return binaryNode->getLeft()->getType().getInterfaceBlock();
+ }
+ }
+
+ const TIntermSymbol *symbolNode = node->getAsSymbolNode();
+ if (symbolNode)
+ {
+ const TVariable &variable = symbolNode->variable();
+ const TType &variableType = variable.getType();
+
+ if (variableType.getQualifier() == EvqUniform &&
+ variable.symbolType() == SymbolType::UserDefined)
+ {
+ return variableType.getInterfaceBlock();
+ }
+ }
+
+ return nullptr;
+}
+
+const char *GetHLSLAtomicFunctionStringAndLeftParenthesis(TOperator op)
+{
+ switch (op)
+ {
+ case EOpAtomicAdd:
+ return "InterlockedAdd(";
+ case EOpAtomicMin:
+ return "InterlockedMin(";
+ case EOpAtomicMax:
+ return "InterlockedMax(";
+ case EOpAtomicAnd:
+ return "InterlockedAnd(";
+ case EOpAtomicOr:
+ return "InterlockedOr(";
+ case EOpAtomicXor:
+ return "InterlockedXor(";
+ case EOpAtomicExchange:
+ return "InterlockedExchange(";
+ case EOpAtomicCompSwap:
+ return "InterlockedCompareExchange(";
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+bool IsAtomicFunctionForSharedVariableDirectAssign(const TIntermBinary &node)
+{
+ TIntermAggregate *aggregateNode = node.getRight()->getAsAggregate();
+ if (aggregateNode == nullptr)
+ {
+ return false;
+ }
+
+ if (node.getOp() == EOpAssign && BuiltInGroup::IsAtomicMemory(aggregateNode->getOp()))
+ {
+ return !IsInShaderStorageBlock((*aggregateNode->getSequence())[0]->getAsTyped());
+ }
+
+ return false;
+}
+
+const char *kZeros = "_ANGLE_ZEROS_";
+constexpr int kZeroCount = 256;
+std::string DefineZeroArray()
+{
+ std::stringstream ss = sh::InitializeStream<std::stringstream>();
+ // For 'static', if the declaration does not include an initializer, the value is set to zero.
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-variable-syntax
+ ss << "static uint " << kZeros << "[" << kZeroCount << "];\n";
+ return ss.str();
+}
+
+std::string GetZeroInitializer(size_t size)
+{
+ std::stringstream ss = sh::InitializeStream<std::stringstream>();
+ size_t quotient = size / kZeroCount;
+ size_t reminder = size % kZeroCount;
+
+ for (size_t i = 0; i < quotient; ++i)
+ {
+ if (i != 0)
+ {
+ ss << ", ";
+ }
+ ss << kZeros;
+ }
+
+ for (size_t i = 0; i < reminder; ++i)
+ {
+ if (quotient != 0 || i != 0)
+ {
+ ss << ", ";
+ }
+ ss << "0";
+ }
+
+ return ss.str();
+}
+
+} // anonymous namespace
+
+TReferencedBlock::TReferencedBlock(const TInterfaceBlock *aBlock,
+ const TVariable *aInstanceVariable)
+ : block(aBlock), instanceVariable(aInstanceVariable)
+{}
+
+bool OutputHLSL::needStructMapping(TIntermTyped *node)
+{
+ ASSERT(node->getBasicType() == EbtStruct);
+ for (unsigned int n = 0u; getAncestorNode(n) != nullptr; ++n)
+ {
+ TIntermNode *ancestor = getAncestorNode(n);
+ const TIntermBinary *ancestorBinary = ancestor->getAsBinaryNode();
+ if (ancestorBinary)
+ {
+ switch (ancestorBinary->getOp())
+ {
+ case EOpIndexDirectStruct:
+ {
+ const TStructure *structure = ancestorBinary->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index =
+ ancestorBinary->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+ if (field->type()->getStruct() == nullptr)
+ {
+ return false;
+ }
+ break;
+ }
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ break;
+ default:
+ return true;
+ }
+ }
+ else
+ {
+ const TIntermAggregate *ancestorAggregate = ancestor->getAsAggregate();
+ if (ancestorAggregate)
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+ return true;
+}
+
+void OutputHLSL::writeFloat(TInfoSinkBase &out, float f)
+{
+ // This is known not to work for NaN on all drivers but make the best effort to output NaNs
+ // regardless.
+ if ((gl::isInf(f) || gl::isNaN(f)) && mShaderVersion >= 300 &&
+ mOutputType == SH_HLSL_4_1_OUTPUT)
+ {
+ out << "asfloat(" << gl::bitCast<uint32_t>(f) << "u)";
+ }
+ else
+ {
+ out << std::min(FLT_MAX, std::max(-FLT_MAX, f));
+ }
+}
+
+void OutputHLSL::writeSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion)
+{
+ ASSERT(constUnion != nullptr);
+ switch (constUnion->getType())
+ {
+ case EbtFloat:
+ writeFloat(out, constUnion->getFConst());
+ break;
+ case EbtInt:
+ out << constUnion->getIConst();
+ break;
+ case EbtUInt:
+ out << constUnion->getUConst();
+ break;
+ case EbtBool:
+ out << constUnion->getBConst();
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+const TConstantUnion *OutputHLSL::writeConstantUnionArray(TInfoSinkBase &out,
+ const TConstantUnion *const constUnion,
+ const size_t size)
+{
+ const TConstantUnion *constUnionIterated = constUnion;
+ for (size_t i = 0; i < size; i++, constUnionIterated++)
+ {
+ writeSingleConstant(out, constUnionIterated);
+
+ if (i != size - 1)
+ {
+ out << ", ";
+ }
+ }
+ return constUnionIterated;
+}
+
+OutputHLSL::OutputHLSL(sh::GLenum shaderType,
+ ShShaderSpec shaderSpec,
+ int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ const char *sourcePath,
+ ShShaderOutput outputType,
+ int numRenderTargets,
+ int maxDualSourceDrawBuffers,
+ const std::vector<ShaderVariable> &uniforms,
+ const ShCompileOptions &compileOptions,
+ sh::WorkGroupSize workGroupSize,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics,
+ const std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap,
+ const std::vector<InterfaceBlock> &shaderStorageBlocks,
+ bool isEarlyFragmentTestsSpecified)
+ : TIntermTraverser(true, true, true, symbolTable),
+ mShaderType(shaderType),
+ mShaderSpec(shaderSpec),
+ mShaderVersion(shaderVersion),
+ mExtensionBehavior(extensionBehavior),
+ mSourcePath(sourcePath),
+ mOutputType(outputType),
+ mCompileOptions(compileOptions),
+ mInsideFunction(false),
+ mInsideMain(false),
+ mUniformBlockOptimizedMap(uniformBlockOptimizedMap),
+ mNumRenderTargets(numRenderTargets),
+ mMaxDualSourceDrawBuffers(maxDualSourceDrawBuffers),
+ mCurrentFunctionMetadata(nullptr),
+ mWorkGroupSize(workGroupSize),
+ mPerfDiagnostics(perfDiagnostics),
+ mIsEarlyFragmentTestsSpecified(isEarlyFragmentTestsSpecified),
+ mNeedStructMapping(false)
+{
+ mUsesFragColor = false;
+ mUsesFragData = false;
+ mUsesDepthRange = false;
+ mUsesFragCoord = false;
+ mUsesPointCoord = false;
+ mUsesFrontFacing = false;
+ mUsesHelperInvocation = false;
+ mUsesPointSize = false;
+ mUsesInstanceID = false;
+ mHasMultiviewExtensionEnabled =
+ IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview) ||
+ IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview2);
+ mUsesViewID = false;
+ mUsesVertexID = false;
+ mUsesFragDepth = false;
+ mUsesNumWorkGroups = false;
+ mUsesWorkGroupID = false;
+ mUsesLocalInvocationID = false;
+ mUsesGlobalInvocationID = false;
+ mUsesLocalInvocationIndex = false;
+ mUsesXor = false;
+ mUsesDiscardRewriting = false;
+ mUsesNestedBreak = false;
+ mRequiresIEEEStrictCompiling = false;
+ mUseZeroArray = false;
+ mUsesSecondaryColor = false;
+
+ mUniqueIndex = 0;
+
+ mOutputLod0Function = false;
+ mInsideDiscontinuousLoop = false;
+ mNestedLoopDepth = 0;
+
+ mExcessiveLoopIndex = nullptr;
+
+ mStructureHLSL = new StructureHLSL;
+ mTextureFunctionHLSL = new TextureFunctionHLSL;
+ mImageFunctionHLSL = new ImageFunctionHLSL;
+ mAtomicCounterFunctionHLSL =
+ new AtomicCounterFunctionHLSL(compileOptions.forceAtomicValueResolution);
+
+ unsigned int firstUniformRegister = compileOptions.skipD3DConstantRegisterZero ? 1u : 0u;
+ mResourcesHLSL = new ResourcesHLSL(mStructureHLSL, outputType, uniforms, firstUniformRegister);
+
+ if (mOutputType == SH_HLSL_3_0_OUTPUT)
+ {
+ // Fragment shaders need dx_DepthRange, dx_ViewCoords, dx_DepthFront,
+ // and dx_FragCoordOffset.
+ // Vertex shaders need a slightly different set: dx_DepthRange, dx_ViewCoords and
+ // dx_ViewAdjust.
+ if (mShaderType == GL_VERTEX_SHADER)
+ {
+ mResourcesHLSL->reserveUniformRegisters(3);
+ }
+ else
+ {
+ mResourcesHLSL->reserveUniformRegisters(4);
+ }
+ }
+
+ // Reserve registers for the default uniform block and driver constants
+ mResourcesHLSL->reserveUniformBlockRegisters(2);
+
+ mSSBOOutputHLSL = new ShaderStorageBlockOutputHLSL(this, mResourcesHLSL, shaderStorageBlocks);
+}
+
+OutputHLSL::~OutputHLSL()
+{
+ SafeDelete(mSSBOOutputHLSL);
+ SafeDelete(mStructureHLSL);
+ SafeDelete(mResourcesHLSL);
+ SafeDelete(mTextureFunctionHLSL);
+ SafeDelete(mImageFunctionHLSL);
+ SafeDelete(mAtomicCounterFunctionHLSL);
+ for (auto &eqFunction : mStructEqualityFunctions)
+ {
+ SafeDelete(eqFunction);
+ }
+ for (auto &eqFunction : mArrayEqualityFunctions)
+ {
+ SafeDelete(eqFunction);
+ }
+}
+
+void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink)
+{
+ BuiltInFunctionEmulator builtInFunctionEmulator;
+ InitBuiltInFunctionEmulatorForHLSL(&builtInFunctionEmulator);
+ if (mCompileOptions.emulateIsnanFloatFunction)
+ {
+ InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(&builtInFunctionEmulator,
+ mShaderVersion);
+ }
+
+ builtInFunctionEmulator.markBuiltInFunctionsForEmulation(treeRoot);
+
+ // Now that we are done changing the AST, do the analyses need for HLSL generation
+ CallDAG::InitResult success = mCallDag.init(treeRoot, nullptr);
+ ASSERT(success == CallDAG::INITDAG_SUCCESS);
+ mASTMetadataList = CreateASTMetadataHLSL(treeRoot, mCallDag);
+
+ const std::vector<MappedStruct> std140Structs = FlagStd140Structs(treeRoot);
+ // TODO(oetuaho): The std140Structs could be filtered based on which ones actually get used in
+ // the shader code. When we add shader storage blocks we might also consider an alternative
+ // solution, since the struct mapping won't work very well for shader storage blocks.
+
+ // Output the body and footer first to determine what has to go in the header
+ mInfoSinkStack.push(&mBody);
+ treeRoot->traverse(this);
+ mInfoSinkStack.pop();
+
+ mInfoSinkStack.push(&mFooter);
+ mInfoSinkStack.pop();
+
+ mInfoSinkStack.push(&mHeader);
+ header(mHeader, std140Structs, &builtInFunctionEmulator);
+ mInfoSinkStack.pop();
+
+ objSink << mHeader.c_str();
+ objSink << mBody.c_str();
+ objSink << mFooter.c_str();
+
+ builtInFunctionEmulator.cleanup();
+}
+
+const std::map<std::string, unsigned int> &OutputHLSL::getShaderStorageBlockRegisterMap() const
+{
+ return mResourcesHLSL->getShaderStorageBlockRegisterMap();
+}
+
+const std::map<std::string, unsigned int> &OutputHLSL::getUniformBlockRegisterMap() const
+{
+ return mResourcesHLSL->getUniformBlockRegisterMap();
+}
+
+const std::map<std::string, bool> &OutputHLSL::getUniformBlockUseStructuredBufferMap() const
+{
+ return mResourcesHLSL->getUniformBlockUseStructuredBufferMap();
+}
+
+const std::map<std::string, unsigned int> &OutputHLSL::getUniformRegisterMap() const
+{
+ return mResourcesHLSL->getUniformRegisterMap();
+}
+
+unsigned int OutputHLSL::getReadonlyImage2DRegisterIndex() const
+{
+ return mResourcesHLSL->getReadonlyImage2DRegisterIndex();
+}
+
+unsigned int OutputHLSL::getImage2DRegisterIndex() const
+{
+ return mResourcesHLSL->getImage2DRegisterIndex();
+}
+
+const std::set<std::string> &OutputHLSL::getUsedImage2DFunctionNames() const
+{
+ return mImageFunctionHLSL->getUsedImage2DFunctionNames();
+}
+
+TString OutputHLSL::structInitializerString(int indent,
+ const TType &type,
+ const TString &name) const
+{
+ TString init;
+
+ TString indentString;
+ for (int spaces = 0; spaces < indent; spaces++)
+ {
+ indentString += " ";
+ }
+
+ if (type.isArray())
+ {
+ init += indentString + "{\n";
+ for (unsigned int arrayIndex = 0u; arrayIndex < type.getOutermostArraySize(); ++arrayIndex)
+ {
+ TStringStream indexedString = sh::InitializeStream<TStringStream>();
+ indexedString << name << "[" << arrayIndex << "]";
+ TType elementType = type;
+ elementType.toArrayElementType();
+ init += structInitializerString(indent + 1, elementType, indexedString.str());
+ if (arrayIndex < type.getOutermostArraySize() - 1)
+ {
+ init += ",";
+ }
+ init += "\n";
+ }
+ init += indentString + "}";
+ }
+ else if (type.getBasicType() == EbtStruct)
+ {
+ init += indentString + "{\n";
+ const TStructure &structure = *type.getStruct();
+ const TFieldList &fields = structure.fields();
+ for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
+ {
+ const TField &field = *fields[fieldIndex];
+ const TString &fieldName = name + "." + Decorate(field.name());
+ const TType &fieldType = *field.type();
+
+ init += structInitializerString(indent + 1, fieldType, fieldName);
+ if (fieldIndex < fields.size() - 1)
+ {
+ init += ",";
+ }
+ init += "\n";
+ }
+ init += indentString + "}";
+ }
+ else
+ {
+ init += indentString + name;
+ }
+
+ return init;
+}
+
+TString OutputHLSL::generateStructMapping(const std::vector<MappedStruct> &std140Structs) const
+{
+ TString mappedStructs;
+
+ for (auto &mappedStruct : std140Structs)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ mappedStruct.blockDeclarator->getType().getInterfaceBlock();
+ TQualifier qualifier = mappedStruct.blockDeclarator->getType().getQualifier();
+ switch (qualifier)
+ {
+ case EvqUniform:
+ if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ continue;
+ }
+ break;
+ case EvqBuffer:
+ continue;
+ default:
+ UNREACHABLE();
+ return mappedStructs;
+ }
+
+ unsigned int instanceCount = 1u;
+ bool isInstanceArray = mappedStruct.blockDeclarator->isArray();
+ if (isInstanceArray)
+ {
+ instanceCount = mappedStruct.blockDeclarator->getOutermostArraySize();
+ }
+
+ for (unsigned int instanceArrayIndex = 0; instanceArrayIndex < instanceCount;
+ ++instanceArrayIndex)
+ {
+ TString originalName;
+ TString mappedName("map");
+
+ if (mappedStruct.blockDeclarator->variable().symbolType() != SymbolType::Empty)
+ {
+ const ImmutableString &instanceName =
+ mappedStruct.blockDeclarator->variable().name();
+ unsigned int instanceStringArrayIndex = GL_INVALID_INDEX;
+ if (isInstanceArray)
+ instanceStringArrayIndex = instanceArrayIndex;
+ TString instanceString = mResourcesHLSL->InterfaceBlockInstanceString(
+ instanceName, instanceStringArrayIndex);
+ originalName += instanceString;
+ mappedName += instanceString;
+ originalName += ".";
+ mappedName += "_";
+ }
+
+ TString fieldName = Decorate(mappedStruct.field->name());
+ originalName += fieldName;
+ mappedName += fieldName;
+
+ TType *structType = mappedStruct.field->type();
+ mappedStructs +=
+ "static " + Decorate(structType->getStruct()->name()) + " " + mappedName;
+
+ if (structType->isArray())
+ {
+ mappedStructs += ArrayString(*mappedStruct.field->type()).data();
+ }
+
+ mappedStructs += " =\n";
+ mappedStructs += structInitializerString(0, *structType, originalName);
+ mappedStructs += ";\n";
+ }
+ }
+ return mappedStructs;
+}
+
+void OutputHLSL::writeReferencedAttributes(TInfoSinkBase &out) const
+{
+ for (const auto &attribute : mReferencedAttributes)
+ {
+ const TType &type = attribute.second->getType();
+ const ImmutableString &name = attribute.second->name();
+
+ out << "static " << TypeString(type) << " " << Decorate(name) << ArrayString(type) << " = "
+ << zeroInitializer(type) << ";\n";
+ }
+}
+
+void OutputHLSL::writeReferencedVaryings(TInfoSinkBase &out) const
+{
+ for (const auto &varying : mReferencedVaryings)
+ {
+ const TType &type = varying.second->getType();
+
+ // Program linking depends on this exact format
+ out << "static " << InterpolationString(type.getQualifier()) << " " << TypeString(type)
+ << " " << DecorateVariableIfNeeded(*varying.second) << ArrayString(type) << " = "
+ << zeroInitializer(type) << ";\n";
+ }
+}
+
+void OutputHLSL::header(TInfoSinkBase &out,
+ const std::vector<MappedStruct> &std140Structs,
+ const BuiltInFunctionEmulator *builtInFunctionEmulator) const
+{
+ TString mappedStructs;
+ if (mNeedStructMapping)
+ {
+ mappedStructs = generateStructMapping(std140Structs);
+ }
+
+ // Suppress some common warnings:
+ // 3556 : Integer divides might be much slower, try using uints if possible.
+ // 3571 : The pow(f, e) intrinsic function won't work for negative f, use abs(f) or
+ // conditionally handle negative values if you expect them.
+ out << "#pragma warning( disable: 3556 3571 )\n";
+
+ out << mStructureHLSL->structsHeader();
+
+ mResourcesHLSL->uniformsHeader(out, mOutputType, mReferencedUniforms, mSymbolTable);
+ out << mResourcesHLSL->uniformBlocksHeader(mReferencedUniformBlocks, mUniformBlockOptimizedMap);
+ mSSBOOutputHLSL->writeShaderStorageBlocksHeader(mShaderType, out);
+
+ if (!mEqualityFunctions.empty())
+ {
+ out << "\n// Equality functions\n\n";
+ for (const auto &eqFunction : mEqualityFunctions)
+ {
+ out << eqFunction->functionDefinition << "\n";
+ }
+ }
+ if (!mArrayAssignmentFunctions.empty())
+ {
+ out << "\n// Assignment functions\n\n";
+ for (const auto &assignmentFunction : mArrayAssignmentFunctions)
+ {
+ out << assignmentFunction.functionDefinition << "\n";
+ }
+ }
+ if (!mArrayConstructIntoFunctions.empty())
+ {
+ out << "\n// Array constructor functions\n\n";
+ for (const auto &constructIntoFunction : mArrayConstructIntoFunctions)
+ {
+ out << constructIntoFunction.functionDefinition << "\n";
+ }
+ }
+
+ if (mUsesDiscardRewriting)
+ {
+ out << "#define ANGLE_USES_DISCARD_REWRITING\n";
+ }
+
+ if (mUsesNestedBreak)
+ {
+ out << "#define ANGLE_USES_NESTED_BREAK\n";
+ }
+
+ if (mRequiresIEEEStrictCompiling)
+ {
+ out << "#define ANGLE_REQUIRES_IEEE_STRICT_COMPILING\n";
+ }
+
+ out << "#ifdef ANGLE_ENABLE_LOOP_FLATTEN\n"
+ "#define LOOP [loop]\n"
+ "#define FLATTEN [flatten]\n"
+ "#else\n"
+ "#define LOOP\n"
+ "#define FLATTEN\n"
+ "#endif\n";
+
+ // array stride for atomic counter buffers is always 4 per original extension
+ // ARB_shader_atomic_counters and discussion on
+ // https://github.com/KhronosGroup/OpenGL-API/issues/5
+ out << "\n#define ATOMIC_COUNTER_ARRAY_STRIDE 4\n\n";
+
+ if (mUseZeroArray)
+ {
+ out << DefineZeroArray() << "\n";
+ }
+
+ if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ const bool usingMRTExtension =
+ IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers);
+ const bool usingBFEExtension =
+ IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_blend_func_extended);
+
+ out << "// Varyings\n";
+ writeReferencedVaryings(out);
+ out << "\n";
+
+ if ((IsDesktopGLSpec(mShaderSpec) && mShaderVersion >= 130) ||
+ (!IsDesktopGLSpec(mShaderSpec) && mShaderVersion >= 300))
+ {
+ for (const auto &outputVariable : mReferencedOutputVariables)
+ {
+ const ImmutableString &variableName = outputVariable.second->name();
+ const TType &variableType = outputVariable.second->getType();
+
+ out << "static " << TypeString(variableType) << " out_" << variableName
+ << ArrayString(variableType) << " = " << zeroInitializer(variableType) << ";\n";
+ }
+ }
+ else
+ {
+ const unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1;
+
+ out << "static float4 gl_Color[" << numColorValues
+ << "] =\n"
+ "{\n";
+ for (unsigned int i = 0; i < numColorValues; i++)
+ {
+ out << " float4(0, 0, 0, 0)";
+ if (i + 1 != numColorValues)
+ {
+ out << ",";
+ }
+ out << "\n";
+ }
+
+ out << "};\n";
+
+ if (usingBFEExtension && mUsesSecondaryColor)
+ {
+ out << "static float4 gl_SecondaryColor[" << mMaxDualSourceDrawBuffers
+ << "] = \n"
+ "{\n";
+ for (int i = 0; i < mMaxDualSourceDrawBuffers; i++)
+ {
+ out << " float4(0, 0, 0, 0)";
+ if (i + 1 != mMaxDualSourceDrawBuffers)
+ {
+ out << ",";
+ }
+ out << "\n";
+ }
+ out << "};\n";
+ }
+ }
+
+ if (mUsesFragDepth)
+ {
+ out << "static float gl_Depth = 0.0;\n";
+ }
+
+ if (mUsesFragCoord)
+ {
+ out << "static float4 gl_FragCoord = float4(0, 0, 0, 0);\n";
+ }
+
+ if (mUsesPointCoord)
+ {
+ out << "static float2 gl_PointCoord = float2(0.5, 0.5);\n";
+ }
+
+ if (mUsesFrontFacing)
+ {
+ out << "static bool gl_FrontFacing = false;\n";
+ }
+
+ if (mUsesHelperInvocation)
+ {
+ out << "static bool gl_HelperInvocation = false;\n";
+ }
+
+ out << "\n";
+
+ if (mUsesDepthRange)
+ {
+ out << "struct gl_DepthRangeParameters\n"
+ "{\n"
+ " float near;\n"
+ " float far;\n"
+ " float diff;\n"
+ "};\n"
+ "\n";
+ }
+
+ if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ out << "cbuffer DriverConstants : register(b1)\n"
+ "{\n";
+
+ if (mUsesDepthRange)
+ {
+ out << " float3 dx_DepthRange : packoffset(c0);\n";
+ }
+
+ if (mUsesFragCoord)
+ {
+ out << " float4 dx_ViewCoords : packoffset(c1);\n";
+ out << " float2 dx_FragCoordOffset : packoffset(c3);\n";
+ }
+
+ if (mUsesFragCoord || mUsesFrontFacing)
+ {
+ out << " float3 dx_DepthFront : packoffset(c2);\n";
+ }
+
+ if (mUsesFragCoord)
+ {
+ // dx_ViewScale is only used in the fragment shader to correct
+ // the value for glFragCoord if necessary
+ out << " float2 dx_ViewScale : packoffset(c3.z);\n";
+ }
+
+ if (mHasMultiviewExtensionEnabled)
+ {
+ // We have to add a value which we can use to keep track of which multi-view code
+ // path is to be selected in the GS.
+ out << " float multiviewSelectViewportIndex : packoffset(c4.x);\n";
+ }
+
+ if (mOutputType == SH_HLSL_4_1_OUTPUT)
+ {
+ unsigned int registerIndex = 5;
+ mResourcesHLSL->samplerMetadataUniforms(out, registerIndex);
+ // Sampler metadata struct must be two 4-vec, 32 bytes.
+ registerIndex += mResourcesHLSL->getSamplerCount() * 2;
+ mResourcesHLSL->imageMetadataUniforms(out, registerIndex);
+ }
+
+ out << "};\n";
+
+ if (mOutputType == SH_HLSL_4_1_OUTPUT && mResourcesHLSL->hasImages())
+ {
+ out << kImage2DFunctionString << "\n";
+ }
+ }
+ else
+ {
+ if (mUsesDepthRange)
+ {
+ out << "uniform float3 dx_DepthRange : register(c0);";
+ }
+
+ if (mUsesFragCoord)
+ {
+ out << "uniform float4 dx_ViewCoords : register(c1);\n";
+ }
+
+ if (mUsesFragCoord || mUsesFrontFacing)
+ {
+ out << "uniform float3 dx_DepthFront : register(c2);\n";
+ out << "uniform float2 dx_FragCoordOffset : register(c3);\n";
+ }
+ }
+
+ out << "\n";
+
+ if (mUsesDepthRange)
+ {
+ out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, "
+ "dx_DepthRange.y, dx_DepthRange.z};\n"
+ "\n";
+ }
+
+ if (usingMRTExtension && mNumRenderTargets > 1)
+ {
+ out << "#define GL_USES_MRT\n";
+ }
+
+ if (mUsesFragColor)
+ {
+ out << "#define GL_USES_FRAG_COLOR\n";
+ }
+
+ if (mUsesFragData)
+ {
+ out << "#define GL_USES_FRAG_DATA\n";
+ }
+
+ if (mShaderVersion < 300 && usingBFEExtension && mUsesSecondaryColor)
+ {
+ out << "#define GL_USES_SECONDARY_COLOR\n";
+ }
+ }
+ else if (mShaderType == GL_VERTEX_SHADER)
+ {
+ out << "// Attributes\n";
+ writeReferencedAttributes(out);
+ out << "\n"
+ "static float4 gl_Position = float4(0, 0, 0, 0);\n";
+
+ if (mUsesPointSize)
+ {
+ out << "static float gl_PointSize = float(1);\n";
+ }
+
+ if (mUsesInstanceID)
+ {
+ out << "static int gl_InstanceID;";
+ }
+
+ if (mUsesVertexID)
+ {
+ out << "static int gl_VertexID;";
+ }
+
+ out << "\n"
+ "// Varyings\n";
+ writeReferencedVaryings(out);
+ out << "\n";
+
+ if (mUsesDepthRange)
+ {
+ out << "struct gl_DepthRangeParameters\n"
+ "{\n"
+ " float near;\n"
+ " float far;\n"
+ " float diff;\n"
+ "};\n"
+ "\n";
+ }
+
+ if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ out << "cbuffer DriverConstants : register(b1)\n"
+ "{\n";
+
+ if (mUsesDepthRange)
+ {
+ out << " float3 dx_DepthRange : packoffset(c0);\n";
+ }
+
+ // dx_ViewAdjust and dx_ViewCoords will only be used in Feature Level 9
+ // shaders. However, we declare it for all shaders (including Feature Level 10+).
+ // The bytecode is the same whether we declare it or not, since D3DCompiler removes it
+ // if it's unused.
+ out << " float4 dx_ViewAdjust : packoffset(c1);\n";
+ out << " float2 dx_ViewCoords : packoffset(c2);\n";
+ out << " float2 dx_ViewScale : packoffset(c3);\n";
+
+ if (mHasMultiviewExtensionEnabled)
+ {
+ // We have to add a value which we can use to keep track of which multi-view code
+ // path is to be selected in the GS.
+ out << " float multiviewSelectViewportIndex : packoffset(c3.z);\n";
+ }
+
+ out << " float clipControlOrigin : packoffset(c3.w);\n";
+ out << " float clipControlZeroToOne : packoffset(c4);\n";
+
+ if (mOutputType == SH_HLSL_4_1_OUTPUT)
+ {
+ mResourcesHLSL->samplerMetadataUniforms(out, 5);
+ }
+
+ if (mUsesVertexID)
+ {
+ out << " uint dx_VertexID : packoffset(c4.y);\n";
+ }
+
+ out << "};\n"
+ "\n";
+ }
+ else
+ {
+ if (mUsesDepthRange)
+ {
+ out << "uniform float3 dx_DepthRange : register(c0);\n";
+ }
+
+ out << "uniform float4 dx_ViewAdjust : register(c1);\n";
+ out << "uniform float2 dx_ViewCoords : register(c2);\n";
+
+ out << "static const float clipControlOrigin = -1.0f;\n";
+ out << "static const float clipControlZeroToOne = 0.0f;\n";
+
+ out << "\n";
+ }
+
+ if (mUsesDepthRange)
+ {
+ out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, "
+ "dx_DepthRange.y, dx_DepthRange.z};\n"
+ "\n";
+ }
+ }
+ else // Compute shader
+ {
+ ASSERT(mShaderType == GL_COMPUTE_SHADER);
+
+ out << "cbuffer DriverConstants : register(b1)\n"
+ "{\n";
+ if (mUsesNumWorkGroups)
+ {
+ out << " uint3 gl_NumWorkGroups : packoffset(c0);\n";
+ }
+ ASSERT(mOutputType == SH_HLSL_4_1_OUTPUT);
+ unsigned int registerIndex = 1;
+ mResourcesHLSL->samplerMetadataUniforms(out, registerIndex);
+ // Sampler metadata struct must be two 4-vec, 32 bytes.
+ registerIndex += mResourcesHLSL->getSamplerCount() * 2;
+ mResourcesHLSL->imageMetadataUniforms(out, registerIndex);
+ out << "};\n";
+
+ out << kImage2DFunctionString << "\n";
+
+ std::ostringstream systemValueDeclaration = sh::InitializeStream<std::ostringstream>();
+ std::ostringstream glBuiltinInitialization = sh::InitializeStream<std::ostringstream>();
+
+ systemValueDeclaration << "\nstruct CS_INPUT\n{\n";
+ glBuiltinInitialization << "\nvoid initGLBuiltins(CS_INPUT input)\n"
+ << "{\n";
+
+ if (mUsesWorkGroupID)
+ {
+ out << "static uint3 gl_WorkGroupID = uint3(0, 0, 0);\n";
+ systemValueDeclaration << " uint3 dx_WorkGroupID : "
+ << "SV_GroupID;\n";
+ glBuiltinInitialization << " gl_WorkGroupID = input.dx_WorkGroupID;\n";
+ }
+
+ if (mUsesLocalInvocationID)
+ {
+ out << "static uint3 gl_LocalInvocationID = uint3(0, 0, 0);\n";
+ systemValueDeclaration << " uint3 dx_LocalInvocationID : "
+ << "SV_GroupThreadID;\n";
+ glBuiltinInitialization << " gl_LocalInvocationID = input.dx_LocalInvocationID;\n";
+ }
+
+ if (mUsesGlobalInvocationID)
+ {
+ out << "static uint3 gl_GlobalInvocationID = uint3(0, 0, 0);\n";
+ systemValueDeclaration << " uint3 dx_GlobalInvocationID : "
+ << "SV_DispatchThreadID;\n";
+ glBuiltinInitialization << " gl_GlobalInvocationID = input.dx_GlobalInvocationID;\n";
+ }
+
+ if (mUsesLocalInvocationIndex)
+ {
+ out << "static uint gl_LocalInvocationIndex = uint(0);\n";
+ systemValueDeclaration << " uint dx_LocalInvocationIndex : "
+ << "SV_GroupIndex;\n";
+ glBuiltinInitialization
+ << " gl_LocalInvocationIndex = input.dx_LocalInvocationIndex;\n";
+ }
+
+ systemValueDeclaration << "};\n\n";
+ glBuiltinInitialization << "};\n\n";
+
+ out << systemValueDeclaration.str();
+ out << glBuiltinInitialization.str();
+ }
+
+ if (!mappedStructs.empty())
+ {
+ out << "// Structures from std140 blocks with padding removed\n";
+ out << "\n";
+ out << mappedStructs;
+ out << "\n";
+ }
+
+ bool getDimensionsIgnoresBaseLevel = mCompileOptions.HLSLGetDimensionsIgnoresBaseLevel;
+ mTextureFunctionHLSL->textureFunctionHeader(out, mOutputType, getDimensionsIgnoresBaseLevel);
+ mImageFunctionHLSL->imageFunctionHeader(out);
+ mAtomicCounterFunctionHLSL->atomicCounterFunctionHeader(out);
+
+ if (mUsesFragCoord)
+ {
+ out << "#define GL_USES_FRAG_COORD\n";
+ }
+
+ if (mUsesPointCoord)
+ {
+ out << "#define GL_USES_POINT_COORD\n";
+ }
+
+ if (mUsesFrontFacing)
+ {
+ out << "#define GL_USES_FRONT_FACING\n";
+ }
+
+ if (mUsesHelperInvocation)
+ {
+ out << "#define GL_USES_HELPER_INVOCATION\n";
+ }
+
+ if (mUsesPointSize)
+ {
+ out << "#define GL_USES_POINT_SIZE\n";
+ }
+
+ if (mHasMultiviewExtensionEnabled)
+ {
+ out << "#define GL_ANGLE_MULTIVIEW_ENABLED\n";
+ }
+
+ if (mUsesVertexID)
+ {
+ out << "#define GL_USES_VERTEX_ID\n";
+ }
+
+ if (mUsesViewID)
+ {
+ out << "#define GL_USES_VIEW_ID\n";
+ }
+
+ if (mUsesFragDepth)
+ {
+ out << "#define GL_USES_FRAG_DEPTH\n";
+ }
+
+ if (mUsesDepthRange)
+ {
+ out << "#define GL_USES_DEPTH_RANGE\n";
+ }
+
+ if (mUsesXor)
+ {
+ out << "bool xor(bool p, bool q)\n"
+ "{\n"
+ " return (p || q) && !(p && q);\n"
+ "}\n"
+ "\n";
+ }
+
+ builtInFunctionEmulator->outputEmulatedFunctions(out);
+}
+
+void OutputHLSL::visitSymbol(TIntermSymbol *node)
+{
+ const TVariable &variable = node->variable();
+
+ // Empty symbols can only appear in declarations and function arguments, and in either of those
+ // cases the symbol nodes are not visited.
+ ASSERT(variable.symbolType() != SymbolType::Empty);
+
+ TInfoSinkBase &out = getInfoSink();
+
+ // Handle accessing std140 structs by value
+ if (IsInStd140UniformBlock(node) && node->getBasicType() == EbtStruct &&
+ needStructMapping(node))
+ {
+ mNeedStructMapping = true;
+ out << "map";
+ }
+
+ const ImmutableString &name = variable.name();
+ const TSymbolUniqueId &uniqueId = variable.uniqueId();
+
+ if (name == "gl_DepthRange")
+ {
+ mUsesDepthRange = true;
+ out << name;
+ }
+ else if (IsAtomicCounter(variable.getType().getBasicType()))
+ {
+ const TType &variableType = variable.getType();
+ if (variableType.getQualifier() == EvqUniform)
+ {
+ TLayoutQualifier layout = variableType.getLayoutQualifier();
+ mReferencedUniforms[uniqueId.get()] = &variable;
+ out << getAtomicCounterNameForBinding(layout.binding) << ", " << layout.offset;
+ }
+ else
+ {
+ TString varName = DecorateVariableIfNeeded(variable);
+ out << varName << ", " << varName << "_offset";
+ }
+ }
+ else
+ {
+ const TType &variableType = variable.getType();
+ TQualifier qualifier = variable.getType().getQualifier();
+
+ ensureStructDefined(variableType);
+
+ if (qualifier == EvqUniform)
+ {
+ const TInterfaceBlock *interfaceBlock = variableType.getInterfaceBlock();
+
+ if (interfaceBlock)
+ {
+ if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ const TVariable *instanceVariable = nullptr;
+ if (variableType.isInterfaceBlock())
+ {
+ instanceVariable = &variable;
+ }
+ mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] =
+ new TReferencedBlock(interfaceBlock, instanceVariable);
+ }
+ }
+ else
+ {
+ mReferencedUniforms[uniqueId.get()] = &variable;
+ }
+
+ out << DecorateVariableIfNeeded(variable);
+ }
+ else if (qualifier == EvqBuffer)
+ {
+ UNREACHABLE();
+ }
+ else if (qualifier == EvqAttribute || qualifier == EvqVertexIn)
+ {
+ mReferencedAttributes[uniqueId.get()] = &variable;
+ out << Decorate(name);
+ }
+ else if (IsVarying(qualifier))
+ {
+ mReferencedVaryings[uniqueId.get()] = &variable;
+ out << DecorateVariableIfNeeded(variable);
+ if (variable.symbolType() == SymbolType::AngleInternal && name == "ViewID_OVR")
+ {
+ mUsesViewID = true;
+ }
+ }
+ else if (qualifier == EvqFragmentOut)
+ {
+ mReferencedOutputVariables[uniqueId.get()] = &variable;
+ out << "out_" << name;
+ }
+ else if (qualifier == EvqFragColor)
+ {
+ out << "gl_Color[0]";
+ mUsesFragColor = true;
+ }
+ else if (qualifier == EvqFragData)
+ {
+ out << "gl_Color";
+ mUsesFragData = true;
+ }
+ else if (qualifier == EvqSecondaryFragColorEXT)
+ {
+ out << "gl_SecondaryColor[0]";
+ mUsesSecondaryColor = true;
+ }
+ else if (qualifier == EvqSecondaryFragDataEXT)
+ {
+ out << "gl_SecondaryColor";
+ mUsesSecondaryColor = true;
+ }
+ else if (qualifier == EvqFragCoord)
+ {
+ mUsesFragCoord = true;
+ out << name;
+ }
+ else if (qualifier == EvqPointCoord)
+ {
+ mUsesPointCoord = true;
+ out << name;
+ }
+ else if (qualifier == EvqFrontFacing)
+ {
+ mUsesFrontFacing = true;
+ out << name;
+ }
+ else if (qualifier == EvqHelperInvocation)
+ {
+ mUsesHelperInvocation = true;
+ out << name;
+ }
+ else if (qualifier == EvqPointSize)
+ {
+ mUsesPointSize = true;
+ out << name;
+ }
+ else if (qualifier == EvqInstanceID)
+ {
+ mUsesInstanceID = true;
+ out << name;
+ }
+ else if (qualifier == EvqVertexID)
+ {
+ mUsesVertexID = true;
+ out << name;
+ }
+ else if (name == "gl_FragDepthEXT" || name == "gl_FragDepth")
+ {
+ mUsesFragDepth = true;
+ out << "gl_Depth";
+ }
+ else if (qualifier == EvqNumWorkGroups)
+ {
+ mUsesNumWorkGroups = true;
+ out << name;
+ }
+ else if (qualifier == EvqWorkGroupID)
+ {
+ mUsesWorkGroupID = true;
+ out << name;
+ }
+ else if (qualifier == EvqLocalInvocationID)
+ {
+ mUsesLocalInvocationID = true;
+ out << name;
+ }
+ else if (qualifier == EvqGlobalInvocationID)
+ {
+ mUsesGlobalInvocationID = true;
+ out << name;
+ }
+ else if (qualifier == EvqLocalInvocationIndex)
+ {
+ mUsesLocalInvocationIndex = true;
+ out << name;
+ }
+ else
+ {
+ out << DecorateVariableIfNeeded(variable);
+ }
+ }
+}
+
+void OutputHLSL::outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out)
+{
+ if (type.isScalar() && !type.isArray())
+ {
+ if (op == EOpEqual)
+ {
+ outputTriplet(out, visit, "(", " == ", ")");
+ }
+ else
+ {
+ outputTriplet(out, visit, "(", " != ", ")");
+ }
+ }
+ else
+ {
+ if (visit == PreVisit && op == EOpNotEqual)
+ {
+ out << "!";
+ }
+
+ if (type.isArray())
+ {
+ const TString &functionName = addArrayEqualityFunction(type);
+ outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")");
+ }
+ else if (type.getBasicType() == EbtStruct)
+ {
+ const TStructure &structure = *type.getStruct();
+ const TString &functionName = addStructEqualityFunction(structure);
+ outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")");
+ }
+ else
+ {
+ ASSERT(type.isMatrix() || type.isVector());
+ outputTriplet(out, visit, "all(", " == ", ")");
+ }
+ }
+}
+
+void OutputHLSL::outputAssign(Visit visit, const TType &type, TInfoSinkBase &out)
+{
+ if (type.isArray())
+ {
+ const TString &functionName = addArrayAssignmentFunction(type);
+ outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")");
+ }
+ else
+ {
+ outputTriplet(out, visit, "(", " = ", ")");
+ }
+}
+
+bool OutputHLSL::ancestorEvaluatesToSamplerInStruct()
+{
+ for (unsigned int n = 0u; getAncestorNode(n) != nullptr; ++n)
+ {
+ TIntermNode *ancestor = getAncestorNode(n);
+ const TIntermBinary *ancestorBinary = ancestor->getAsBinaryNode();
+ if (ancestorBinary == nullptr)
+ {
+ return false;
+ }
+ switch (ancestorBinary->getOp())
+ {
+ case EOpIndexDirectStruct:
+ {
+ const TStructure *structure = ancestorBinary->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index =
+ ancestorBinary->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+ if (IsSampler(field->type()->getBasicType()))
+ {
+ return true;
+ }
+ break;
+ }
+ case EOpIndexDirect:
+ break;
+ default:
+ // Returning a sampler from indirect indexing is not supported.
+ return false;
+ }
+ }
+ return false;
+}
+
+bool OutputHLSL::visitSwizzle(Visit visit, TIntermSwizzle *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+ if (visit == PostVisit)
+ {
+ out << ".";
+ node->writeOffsetsAsXYZW(&out);
+ }
+ return true;
+}
+
+bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ switch (node->getOp())
+ {
+ case EOpComma:
+ outputTriplet(out, visit, "(", ", ", ")");
+ break;
+ case EOpAssign:
+ if (node->isArray())
+ {
+ TIntermAggregate *rightAgg = node->getRight()->getAsAggregate();
+ if (rightAgg != nullptr && rightAgg->isConstructor())
+ {
+ const TString &functionName = addArrayConstructIntoFunction(node->getType());
+ out << functionName << "(";
+ node->getLeft()->traverse(this);
+ TIntermSequence *seq = rightAgg->getSequence();
+ for (auto &arrayElement : *seq)
+ {
+ out << ", ";
+ arrayElement->traverse(this);
+ }
+ out << ")";
+ return false;
+ }
+ // ArrayReturnValueToOutParameter should have eliminated expressions where a
+ // function call is assigned.
+ ASSERT(rightAgg == nullptr);
+ }
+ // Assignment expressions with atomic functions should be transformed into atomic
+ // function calls in HLSL.
+ // e.g. original_value = atomicAdd(dest, value) should be translated into
+ // InterlockedAdd(dest, value, original_value);
+ else if (IsAtomicFunctionForSharedVariableDirectAssign(*node))
+ {
+ TIntermAggregate *atomicFunctionNode = node->getRight()->getAsAggregate();
+ TOperator atomicFunctionOp = atomicFunctionNode->getOp();
+ out << GetHLSLAtomicFunctionStringAndLeftParenthesis(atomicFunctionOp);
+ TIntermSequence *argumentSeq = atomicFunctionNode->getSequence();
+ ASSERT(argumentSeq->size() >= 2u);
+ for (auto &argument : *argumentSeq)
+ {
+ argument->traverse(this);
+ out << ", ";
+ }
+ node->getLeft()->traverse(this);
+ out << ")";
+ return false;
+ }
+ else if (IsInShaderStorageBlock(node->getLeft()))
+ {
+ mSSBOOutputHLSL->outputStoreFunctionCallPrefix(node->getLeft());
+ out << ", ";
+ if (IsInShaderStorageBlock(node->getRight()))
+ {
+ mSSBOOutputHLSL->outputLoadFunctionCall(node->getRight());
+ }
+ else
+ {
+ node->getRight()->traverse(this);
+ }
+
+ out << ")";
+ return false;
+ }
+ else if (IsInShaderStorageBlock(node->getRight()))
+ {
+ node->getLeft()->traverse(this);
+ out << " = ";
+ mSSBOOutputHLSL->outputLoadFunctionCall(node->getRight());
+ return false;
+ }
+
+ outputAssign(visit, node->getType(), out);
+ break;
+ case EOpInitialize:
+ if (visit == PreVisit)
+ {
+ TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode();
+ ASSERT(symbolNode);
+ TIntermTyped *initializer = node->getRight();
+
+ // Global initializers must be constant at this point.
+ ASSERT(symbolNode->getQualifier() != EvqGlobal || initializer->hasConstantValue());
+
+ // GLSL allows to write things like "float x = x;" where a new variable x is defined
+ // and the value of an existing variable x is assigned. HLSL uses C semantics (the
+ // new variable is created before the assignment is evaluated), so we need to
+ // convert
+ // this to "float t = x, x = t;".
+ if (writeSameSymbolInitializer(out, symbolNode, initializer))
+ {
+ // Skip initializing the rest of the expression
+ return false;
+ }
+ else if (writeConstantInitialization(out, symbolNode, initializer))
+ {
+ return false;
+ }
+ }
+ else if (visit == InVisit)
+ {
+ out << " = ";
+ if (IsInShaderStorageBlock(node->getRight()))
+ {
+ mSSBOOutputHLSL->outputLoadFunctionCall(node->getRight());
+ return false;
+ }
+ }
+ break;
+ case EOpAddAssign:
+ outputTriplet(out, visit, "(", " += ", ")");
+ break;
+ case EOpSubAssign:
+ outputTriplet(out, visit, "(", " -= ", ")");
+ break;
+ case EOpMulAssign:
+ outputTriplet(out, visit, "(", " *= ", ")");
+ break;
+ case EOpVectorTimesScalarAssign:
+ outputTriplet(out, visit, "(", " *= ", ")");
+ break;
+ case EOpMatrixTimesScalarAssign:
+ outputTriplet(out, visit, "(", " *= ", ")");
+ break;
+ case EOpVectorTimesMatrixAssign:
+ if (visit == PreVisit)
+ {
+ out << "(";
+ }
+ else if (visit == InVisit)
+ {
+ out << " = mul(";
+ node->getLeft()->traverse(this);
+ out << ", transpose(";
+ }
+ else
+ {
+ out << ")))";
+ }
+ break;
+ case EOpMatrixTimesMatrixAssign:
+ if (visit == PreVisit)
+ {
+ out << "(";
+ }
+ else if (visit == InVisit)
+ {
+ out << " = transpose(mul(transpose(";
+ node->getLeft()->traverse(this);
+ out << "), transpose(";
+ }
+ else
+ {
+ out << "))))";
+ }
+ break;
+ case EOpDivAssign:
+ outputTriplet(out, visit, "(", " /= ", ")");
+ break;
+ case EOpIModAssign:
+ outputTriplet(out, visit, "(", " %= ", ")");
+ break;
+ case EOpBitShiftLeftAssign:
+ outputTriplet(out, visit, "(", " <<= ", ")");
+ break;
+ case EOpBitShiftRightAssign:
+ outputTriplet(out, visit, "(", " >>= ", ")");
+ break;
+ case EOpBitwiseAndAssign:
+ outputTriplet(out, visit, "(", " &= ", ")");
+ break;
+ case EOpBitwiseXorAssign:
+ outputTriplet(out, visit, "(", " ^= ", ")");
+ break;
+ case EOpBitwiseOrAssign:
+ outputTriplet(out, visit, "(", " |= ", ")");
+ break;
+ case EOpIndexDirect:
+ {
+ const TType &leftType = node->getLeft()->getType();
+ if (leftType.isInterfaceBlock())
+ {
+ if (visit == PreVisit)
+ {
+ TIntermSymbol *instanceArraySymbol = node->getLeft()->getAsSymbolNode();
+ const TInterfaceBlock *interfaceBlock = leftType.getInterfaceBlock();
+
+ ASSERT(leftType.getQualifier() == EvqUniform);
+ if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] =
+ new TReferencedBlock(interfaceBlock, &instanceArraySymbol->variable());
+ }
+ const int arrayIndex = node->getRight()->getAsConstantUnion()->getIConst(0);
+ out << mResourcesHLSL->InterfaceBlockInstanceString(
+ instanceArraySymbol->getName(), arrayIndex);
+ return false;
+ }
+ }
+ else if (ancestorEvaluatesToSamplerInStruct())
+ {
+ // All parts of an expression that access a sampler in a struct need to use _ as
+ // separator to access the sampler variable that has been moved out of the struct.
+ outputTriplet(out, visit, "", "_", "");
+ }
+ else if (IsAtomicCounter(leftType.getBasicType()))
+ {
+ outputTriplet(out, visit, "", " + (", ") * ATOMIC_COUNTER_ARRAY_STRIDE");
+ }
+ else
+ {
+ outputTriplet(out, visit, "", "[", "]");
+ if (visit == PostVisit)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ GetInterfaceBlockOfUniformBlockNearestIndexOperator(node->getLeft());
+ if (interfaceBlock &&
+ mUniformBlockOptimizedMap.count(interfaceBlock->uniqueId().get()) != 0)
+ {
+ // If the uniform block member's type is not structure, we had explicitly
+ // packed the member into a structure, so need to add an operator of field
+ // slection.
+ const TField *field = interfaceBlock->fields()[0];
+ const TType *fieldType = field->type();
+ if (fieldType->isMatrix() || fieldType->isVectorArray() ||
+ fieldType->isScalarArray())
+ {
+ out << "." << Decorate(field->name());
+ }
+ }
+ }
+ }
+ }
+ break;
+ case EOpIndexIndirect:
+ {
+ // We do not currently support indirect references to interface blocks
+ ASSERT(node->getLeft()->getBasicType() != EbtInterfaceBlock);
+
+ const TType &leftType = node->getLeft()->getType();
+ if (IsAtomicCounter(leftType.getBasicType()))
+ {
+ outputTriplet(out, visit, "", " + (", ") * ATOMIC_COUNTER_ARRAY_STRIDE");
+ }
+ else
+ {
+ outputTriplet(out, visit, "", "[", "]");
+ if (visit == PostVisit)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ GetInterfaceBlockOfUniformBlockNearestIndexOperator(node->getLeft());
+ if (interfaceBlock &&
+ mUniformBlockOptimizedMap.count(interfaceBlock->uniqueId().get()) != 0)
+ {
+ // If the uniform block member's type is not structure, we had explicitly
+ // packed the member into a structure, so need to add an operator of field
+ // slection.
+ const TField *field = interfaceBlock->fields()[0];
+ const TType *fieldType = field->type();
+ if (fieldType->isMatrix() || fieldType->isVectorArray() ||
+ fieldType->isScalarArray())
+ {
+ out << "." << Decorate(field->name());
+ }
+ }
+ }
+ }
+ break;
+ }
+ case EOpIndexDirectStruct:
+ {
+ const TStructure *structure = node->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+
+ // In cases where indexing returns a sampler, we need to access the sampler variable
+ // that has been moved out of the struct.
+ bool indexingReturnsSampler = IsSampler(field->type()->getBasicType());
+ if (visit == PreVisit && indexingReturnsSampler)
+ {
+ // Samplers extracted from structs have "angle" prefix to avoid name conflicts.
+ // This prefix is only output at the beginning of the indexing expression, which
+ // may have multiple parts.
+ out << "angle";
+ }
+ if (!indexingReturnsSampler)
+ {
+ // All parts of an expression that access a sampler in a struct need to use _ as
+ // separator to access the sampler variable that has been moved out of the struct.
+ indexingReturnsSampler = ancestorEvaluatesToSamplerInStruct();
+ }
+ if (visit == InVisit)
+ {
+ if (indexingReturnsSampler)
+ {
+ out << "_" << field->name();
+ }
+ else
+ {
+ out << "." << DecorateField(field->name(), *structure);
+ }
+
+ return false;
+ }
+ }
+ break;
+ case EOpIndexDirectInterfaceBlock:
+ {
+ ASSERT(!IsInShaderStorageBlock(node->getLeft()));
+ bool structInStd140UniformBlock = node->getBasicType() == EbtStruct &&
+ IsInStd140UniformBlock(node->getLeft()) &&
+ needStructMapping(node);
+ if (visit == PreVisit && structInStd140UniformBlock)
+ {
+ mNeedStructMapping = true;
+ out << "map";
+ }
+ if (visit == InVisit)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ node->getLeft()->getType().getInterfaceBlock();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = interfaceBlock->fields()[index->getIConst(0)];
+ if (structInStd140UniformBlock ||
+ mUniformBlockOptimizedMap.count(interfaceBlock->uniqueId().get()) != 0)
+ {
+ out << "_";
+ }
+ else
+ {
+ out << ".";
+ }
+ out << Decorate(field->name());
+
+ return false;
+ }
+ break;
+ }
+ case EOpAdd:
+ outputTriplet(out, visit, "(", " + ", ")");
+ break;
+ case EOpSub:
+ outputTriplet(out, visit, "(", " - ", ")");
+ break;
+ case EOpMul:
+ outputTriplet(out, visit, "(", " * ", ")");
+ break;
+ case EOpDiv:
+ outputTriplet(out, visit, "(", " / ", ")");
+ break;
+ case EOpIMod:
+ outputTriplet(out, visit, "(", " % ", ")");
+ break;
+ case EOpBitShiftLeft:
+ outputTriplet(out, visit, "(", " << ", ")");
+ break;
+ case EOpBitShiftRight:
+ outputTriplet(out, visit, "(", " >> ", ")");
+ break;
+ case EOpBitwiseAnd:
+ outputTriplet(out, visit, "(", " & ", ")");
+ break;
+ case EOpBitwiseXor:
+ outputTriplet(out, visit, "(", " ^ ", ")");
+ break;
+ case EOpBitwiseOr:
+ outputTriplet(out, visit, "(", " | ", ")");
+ break;
+ case EOpEqual:
+ case EOpNotEqual:
+ outputEqual(visit, node->getLeft()->getType(), node->getOp(), out);
+ break;
+ case EOpLessThan:
+ outputTriplet(out, visit, "(", " < ", ")");
+ break;
+ case EOpGreaterThan:
+ outputTriplet(out, visit, "(", " > ", ")");
+ break;
+ case EOpLessThanEqual:
+ outputTriplet(out, visit, "(", " <= ", ")");
+ break;
+ case EOpGreaterThanEqual:
+ outputTriplet(out, visit, "(", " >= ", ")");
+ break;
+ case EOpVectorTimesScalar:
+ outputTriplet(out, visit, "(", " * ", ")");
+ break;
+ case EOpMatrixTimesScalar:
+ outputTriplet(out, visit, "(", " * ", ")");
+ break;
+ case EOpVectorTimesMatrix:
+ outputTriplet(out, visit, "mul(", ", transpose(", "))");
+ break;
+ case EOpMatrixTimesVector:
+ outputTriplet(out, visit, "mul(transpose(", "), ", ")");
+ break;
+ case EOpMatrixTimesMatrix:
+ outputTriplet(out, visit, "transpose(mul(transpose(", "), transpose(", ")))");
+ break;
+ case EOpLogicalOr:
+ // HLSL doesn't short-circuit ||, so we assume that || affected by short-circuiting have
+ // been unfolded.
+ ASSERT(!node->getRight()->hasSideEffects());
+ outputTriplet(out, visit, "(", " || ", ")");
+ return true;
+ case EOpLogicalXor:
+ mUsesXor = true;
+ outputTriplet(out, visit, "xor(", ", ", ")");
+ break;
+ case EOpLogicalAnd:
+ // HLSL doesn't short-circuit &&, so we assume that && affected by short-circuiting have
+ // been unfolded.
+ ASSERT(!node->getRight()->hasSideEffects());
+ outputTriplet(out, visit, "(", " && ", ")");
+ return true;
+ default:
+ UNREACHABLE();
+ }
+
+ return true;
+}
+
+bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ switch (node->getOp())
+ {
+ case EOpNegative:
+ outputTriplet(out, visit, "(-", "", ")");
+ break;
+ case EOpPositive:
+ outputTriplet(out, visit, "(+", "", ")");
+ break;
+ case EOpLogicalNot:
+ outputTriplet(out, visit, "(!", "", ")");
+ break;
+ case EOpBitwiseNot:
+ outputTriplet(out, visit, "(~", "", ")");
+ break;
+ case EOpPostIncrement:
+ outputTriplet(out, visit, "(", "", "++)");
+ break;
+ case EOpPostDecrement:
+ outputTriplet(out, visit, "(", "", "--)");
+ break;
+ case EOpPreIncrement:
+ outputTriplet(out, visit, "(++", "", ")");
+ break;
+ case EOpPreDecrement:
+ outputTriplet(out, visit, "(--", "", ")");
+ break;
+ case EOpRadians:
+ outputTriplet(out, visit, "radians(", "", ")");
+ break;
+ case EOpDegrees:
+ outputTriplet(out, visit, "degrees(", "", ")");
+ break;
+ case EOpSin:
+ outputTriplet(out, visit, "sin(", "", ")");
+ break;
+ case EOpCos:
+ outputTriplet(out, visit, "cos(", "", ")");
+ break;
+ case EOpTan:
+ outputTriplet(out, visit, "tan(", "", ")");
+ break;
+ case EOpAsin:
+ outputTriplet(out, visit, "asin(", "", ")");
+ break;
+ case EOpAcos:
+ outputTriplet(out, visit, "acos(", "", ")");
+ break;
+ case EOpAtan:
+ outputTriplet(out, visit, "atan(", "", ")");
+ break;
+ case EOpSinh:
+ outputTriplet(out, visit, "sinh(", "", ")");
+ break;
+ case EOpCosh:
+ outputTriplet(out, visit, "cosh(", "", ")");
+ break;
+ case EOpTanh:
+ case EOpAsinh:
+ case EOpAcosh:
+ case EOpAtanh:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpExp:
+ outputTriplet(out, visit, "exp(", "", ")");
+ break;
+ case EOpLog:
+ outputTriplet(out, visit, "log(", "", ")");
+ break;
+ case EOpExp2:
+ outputTriplet(out, visit, "exp2(", "", ")");
+ break;
+ case EOpLog2:
+ outputTriplet(out, visit, "log2(", "", ")");
+ break;
+ case EOpSqrt:
+ outputTriplet(out, visit, "sqrt(", "", ")");
+ break;
+ case EOpInversesqrt:
+ outputTriplet(out, visit, "rsqrt(", "", ")");
+ break;
+ case EOpAbs:
+ outputTriplet(out, visit, "abs(", "", ")");
+ break;
+ case EOpSign:
+ outputTriplet(out, visit, "sign(", "", ")");
+ break;
+ case EOpFloor:
+ outputTriplet(out, visit, "floor(", "", ")");
+ break;
+ case EOpTrunc:
+ outputTriplet(out, visit, "trunc(", "", ")");
+ break;
+ case EOpRound:
+ outputTriplet(out, visit, "round(", "", ")");
+ break;
+ case EOpRoundEven:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpCeil:
+ outputTriplet(out, visit, "ceil(", "", ")");
+ break;
+ case EOpFract:
+ outputTriplet(out, visit, "frac(", "", ")");
+ break;
+ case EOpIsnan:
+ if (node->getUseEmulatedFunction())
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ else
+ outputTriplet(out, visit, "isnan(", "", ")");
+ mRequiresIEEEStrictCompiling = true;
+ break;
+ case EOpIsinf:
+ outputTriplet(out, visit, "isinf(", "", ")");
+ break;
+ case EOpFloatBitsToInt:
+ outputTriplet(out, visit, "asint(", "", ")");
+ break;
+ case EOpFloatBitsToUint:
+ outputTriplet(out, visit, "asuint(", "", ")");
+ break;
+ case EOpIntBitsToFloat:
+ outputTriplet(out, visit, "asfloat(", "", ")");
+ break;
+ case EOpUintBitsToFloat:
+ outputTriplet(out, visit, "asfloat(", "", ")");
+ break;
+ case EOpPackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackUnorm2x16:
+ case EOpUnpackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpLength:
+ outputTriplet(out, visit, "length(", "", ")");
+ break;
+ case EOpNormalize:
+ outputTriplet(out, visit, "normalize(", "", ")");
+ break;
+ case EOpTranspose:
+ outputTriplet(out, visit, "transpose(", "", ")");
+ break;
+ case EOpDeterminant:
+ outputTriplet(out, visit, "determinant(transpose(", "", "))");
+ break;
+ case EOpInverse:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+
+ case EOpAny:
+ outputTriplet(out, visit, "any(", "", ")");
+ break;
+ case EOpAll:
+ outputTriplet(out, visit, "all(", "", ")");
+ break;
+ case EOpNotComponentWise:
+ outputTriplet(out, visit, "(!", "", ")");
+ break;
+ case EOpBitfieldReverse:
+ outputTriplet(out, visit, "reversebits(", "", ")");
+ break;
+ case EOpBitCount:
+ outputTriplet(out, visit, "countbits(", "", ")");
+ break;
+ case EOpFindLSB:
+ // Note that it's unclear from the HLSL docs what this returns for 0, but this is tested
+ // in GLSLTest and results are consistent with GL.
+ outputTriplet(out, visit, "firstbitlow(", "", ")");
+ break;
+ case EOpFindMSB:
+ // Note that it's unclear from the HLSL docs what this returns for 0 or -1, but this is
+ // tested in GLSLTest and results are consistent with GL.
+ outputTriplet(out, visit, "firstbithigh(", "", ")");
+ break;
+ case EOpArrayLength:
+ {
+ TIntermTyped *operand = node->getOperand();
+ ASSERT(IsInShaderStorageBlock(operand));
+ mSSBOOutputHLSL->outputLengthFunctionCall(operand);
+ return false;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ return true;
+}
+
+ImmutableString OutputHLSL::samplerNamePrefixFromStruct(TIntermTyped *node)
+{
+ if (node->getAsSymbolNode())
+ {
+ ASSERT(node->getAsSymbolNode()->variable().symbolType() != SymbolType::Empty);
+ return node->getAsSymbolNode()->getName();
+ }
+ TIntermBinary *nodeBinary = node->getAsBinaryNode();
+ switch (nodeBinary->getOp())
+ {
+ case EOpIndexDirect:
+ {
+ int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0);
+
+ std::stringstream prefixSink = sh::InitializeStream<std::stringstream>();
+ prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_" << index;
+ return ImmutableString(prefixSink.str());
+ }
+ case EOpIndexDirectStruct:
+ {
+ const TStructure *s = nodeBinary->getLeft()->getAsTyped()->getType().getStruct();
+ int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0);
+ const TField *field = s->fields()[index];
+
+ std::stringstream prefixSink = sh::InitializeStream<std::stringstream>();
+ prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_"
+ << field->name();
+ return ImmutableString(prefixSink.str());
+ }
+ default:
+ UNREACHABLE();
+ return kEmptyImmutableString;
+ }
+}
+
+bool OutputHLSL::visitBlock(Visit visit, TIntermBlock *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ bool isMainBlock = mInsideMain && getParentNode()->getAsFunctionDefinition();
+
+ if (mInsideFunction)
+ {
+ outputLineDirective(out, node->getLine().first_line);
+ out << "{\n";
+ if (isMainBlock)
+ {
+ if (mShaderType == GL_COMPUTE_SHADER)
+ {
+ out << "initGLBuiltins(input);\n";
+ }
+ else
+ {
+ out << "@@ MAIN PROLOGUE @@\n";
+ }
+ }
+ }
+
+ for (TIntermNode *statement : *node->getSequence())
+ {
+ outputLineDirective(out, statement->getLine().first_line);
+
+ statement->traverse(this);
+
+ // Don't output ; after case labels, they're terminated by :
+ // This is needed especially since outputting a ; after a case statement would turn empty
+ // case statements into non-empty case statements, disallowing fall-through from them.
+ // Also the output code is clearer if we don't output ; after statements where it is not
+ // needed:
+ // * if statements
+ // * switch statements
+ // * blocks
+ // * function definitions
+ // * loops (do-while loops output the semicolon in VisitLoop)
+ // * declarations that don't generate output.
+ if (statement->getAsCaseNode() == nullptr && statement->getAsIfElseNode() == nullptr &&
+ statement->getAsBlock() == nullptr && statement->getAsLoopNode() == nullptr &&
+ statement->getAsSwitchNode() == nullptr &&
+ statement->getAsFunctionDefinition() == nullptr &&
+ (statement->getAsDeclarationNode() == nullptr ||
+ IsDeclarationWrittenOut(statement->getAsDeclarationNode())) &&
+ statement->getAsGlobalQualifierDeclarationNode() == nullptr)
+ {
+ out << ";\n";
+ }
+ }
+
+ if (mInsideFunction)
+ {
+ outputLineDirective(out, node->getLine().last_line);
+ if (isMainBlock && shaderNeedsGenerateOutput())
+ {
+ // We could have an empty main, a main function without a branch at the end, or a main
+ // function with a discard statement at the end. In these cases we need to add a return
+ // statement.
+ bool needReturnStatement =
+ node->getSequence()->empty() || !node->getSequence()->back()->getAsBranchNode() ||
+ node->getSequence()->back()->getAsBranchNode()->getFlowOp() != EOpReturn;
+ if (needReturnStatement)
+ {
+ out << "return " << generateOutputCall() << ";\n";
+ }
+ }
+ out << "}\n";
+ }
+
+ return false;
+}
+
+bool OutputHLSL::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ ASSERT(mCurrentFunctionMetadata == nullptr);
+
+ size_t index = mCallDag.findIndex(node->getFunction()->uniqueId());
+ ASSERT(index != CallDAG::InvalidIndex);
+ mCurrentFunctionMetadata = &mASTMetadataList[index];
+
+ const TFunction *func = node->getFunction();
+
+ if (func->isMain())
+ {
+ // The stub strings below are replaced when shader is dynamically defined by its layout:
+ switch (mShaderType)
+ {
+ case GL_VERTEX_SHADER:
+ out << "@@ VERTEX ATTRIBUTES @@\n\n"
+ << "@@ VERTEX OUTPUT @@\n\n"
+ << "VS_OUTPUT main(VS_INPUT input)";
+ break;
+ case GL_FRAGMENT_SHADER:
+ out << "@@ PIXEL OUTPUT @@\n\n";
+ if (mIsEarlyFragmentTestsSpecified)
+ {
+ out << "[earlydepthstencil]\n";
+ }
+ out << "PS_OUTPUT main(@@ PIXEL MAIN PARAMETERS @@)";
+ break;
+ case GL_COMPUTE_SHADER:
+ out << "[numthreads(" << mWorkGroupSize[0] << ", " << mWorkGroupSize[1] << ", "
+ << mWorkGroupSize[2] << ")]\n";
+ out << "void main(CS_INPUT input)";
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ else
+ {
+ out << TypeString(node->getFunctionPrototype()->getType()) << " ";
+ out << DecorateFunctionIfNeeded(func) << DisambiguateFunctionName(func)
+ << (mOutputLod0Function ? "Lod0(" : "(");
+
+ size_t paramCount = func->getParamCount();
+ for (unsigned int i = 0; i < paramCount; i++)
+ {
+ const TVariable *param = func->getParam(i);
+ ensureStructDefined(param->getType());
+
+ writeParameter(param, out);
+
+ if (i < paramCount - 1)
+ {
+ out << ", ";
+ }
+ }
+
+ out << ")\n";
+ }
+
+ mInsideFunction = true;
+ if (func->isMain())
+ {
+ mInsideMain = true;
+ }
+ // The function body node will output braces.
+ node->getBody()->traverse(this);
+ mInsideFunction = false;
+ mInsideMain = false;
+
+ mCurrentFunctionMetadata = nullptr;
+
+ bool needsLod0 = mASTMetadataList[index].mNeedsLod0;
+ if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER)
+ {
+ ASSERT(!node->getFunction()->isMain());
+ mOutputLod0Function = true;
+ node->traverse(this);
+ mOutputLod0Function = false;
+ }
+
+ return false;
+}
+
+bool OutputHLSL::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ if (visit == PreVisit)
+ {
+ TIntermSequence *sequence = node->getSequence();
+ TIntermTyped *declarator = (*sequence)[0]->getAsTyped();
+ ASSERT(sequence->size() == 1);
+ ASSERT(declarator);
+
+ if (IsDeclarationWrittenOut(node))
+ {
+ TInfoSinkBase &out = getInfoSink();
+ ensureStructDefined(declarator->getType());
+
+ if (!declarator->getAsSymbolNode() ||
+ declarator->getAsSymbolNode()->variable().symbolType() !=
+ SymbolType::Empty) // Variable declaration
+ {
+ if (declarator->getQualifier() == EvqShared)
+ {
+ out << "groupshared ";
+ }
+ else if (!mInsideFunction)
+ {
+ out << "static ";
+ }
+
+ out << TypeString(declarator->getType()) + " ";
+
+ TIntermSymbol *symbol = declarator->getAsSymbolNode();
+
+ if (symbol)
+ {
+ symbol->traverse(this);
+ out << ArrayString(symbol->getType());
+ // Temporarily disable shadred memory initialization. It is very slow for D3D11
+ // drivers to compile a compute shader if we add code to initialize a
+ // groupshared array variable with a large array size. And maybe produce
+ // incorrect result. See http://anglebug.com/3226.
+ if (declarator->getQualifier() != EvqShared)
+ {
+ out << " = " + zeroInitializer(symbol->getType());
+ }
+ }
+ else
+ {
+ declarator->traverse(this);
+ }
+ }
+ }
+ else if (IsVaryingOut(declarator->getQualifier()))
+ {
+ TIntermSymbol *symbol = declarator->getAsSymbolNode();
+ ASSERT(symbol); // Varying declarations can't have initializers.
+
+ const TVariable &variable = symbol->variable();
+
+ if (variable.symbolType() != SymbolType::Empty)
+ {
+ // Vertex outputs which are declared but not written to should still be declared to
+ // allow successful linking.
+ mReferencedVaryings[symbol->uniqueId().get()] = &variable;
+ }
+ }
+ }
+ return false;
+}
+
+bool OutputHLSL::visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+{
+ // Do not do any translation
+ return false;
+}
+
+void OutputHLSL::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ size_t index = mCallDag.findIndex(node->getFunction()->uniqueId());
+ // Skip the prototype if it is not implemented (and thus not used)
+ if (index == CallDAG::InvalidIndex)
+ {
+ return;
+ }
+
+ const TFunction *func = node->getFunction();
+
+ TString name = DecorateFunctionIfNeeded(func);
+ out << TypeString(node->getType()) << " " << name << DisambiguateFunctionName(func)
+ << (mOutputLod0Function ? "Lod0(" : "(");
+
+ size_t paramCount = func->getParamCount();
+ for (unsigned int i = 0; i < paramCount; i++)
+ {
+ writeParameter(func->getParam(i), out);
+
+ if (i < paramCount - 1)
+ {
+ out << ", ";
+ }
+ }
+
+ out << ");\n";
+
+ // Also prototype the Lod0 variant if needed
+ bool needsLod0 = mASTMetadataList[index].mNeedsLod0;
+ if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER)
+ {
+ mOutputLod0Function = true;
+ node->traverse(this);
+ mOutputLod0Function = false;
+ }
+}
+
+bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ switch (node->getOp())
+ {
+ case EOpCallFunctionInAST:
+ case EOpCallInternalRawFunction:
+ default:
+ {
+ TIntermSequence *arguments = node->getSequence();
+
+ bool lod0 = (mInsideDiscontinuousLoop || mOutputLod0Function) &&
+ mShaderType == GL_FRAGMENT_SHADER;
+
+ // No raw function is expected.
+ ASSERT(node->getOp() != EOpCallInternalRawFunction);
+
+ if (node->getOp() == EOpCallFunctionInAST)
+ {
+ if (node->isArray())
+ {
+ UNIMPLEMENTED();
+ }
+ size_t index = mCallDag.findIndex(node->getFunction()->uniqueId());
+ ASSERT(index != CallDAG::InvalidIndex);
+ lod0 &= mASTMetadataList[index].mNeedsLod0;
+
+ out << DecorateFunctionIfNeeded(node->getFunction());
+ out << DisambiguateFunctionName(node->getSequence());
+ out << (lod0 ? "Lod0(" : "(");
+ }
+ else if (node->getFunction()->isImageFunction())
+ {
+ const ImmutableString &name = node->getFunction()->name();
+ TType type = (*arguments)[0]->getAsTyped()->getType();
+ const ImmutableString &imageFunctionName = mImageFunctionHLSL->useImageFunction(
+ name, type.getBasicType(), type.getLayoutQualifier().imageInternalFormat,
+ type.getMemoryQualifier().readonly);
+ out << imageFunctionName << "(";
+ }
+ else if (node->getFunction()->isAtomicCounterFunction())
+ {
+ const ImmutableString &name = node->getFunction()->name();
+ ImmutableString atomicFunctionName =
+ mAtomicCounterFunctionHLSL->useAtomicCounterFunction(name);
+ out << atomicFunctionName << "(";
+ }
+ else
+ {
+ const ImmutableString &name = node->getFunction()->name();
+ TBasicType samplerType = (*arguments)[0]->getAsTyped()->getType().getBasicType();
+ int coords = 0; // textureSize(gsampler2DMS) doesn't have a second argument.
+ if (arguments->size() > 1)
+ {
+ coords = (*arguments)[1]->getAsTyped()->getNominalSize();
+ }
+ const ImmutableString &textureFunctionName =
+ mTextureFunctionHLSL->useTextureFunction(name, samplerType, coords,
+ arguments->size(), lod0, mShaderType);
+ out << textureFunctionName << "(";
+ }
+
+ for (TIntermSequence::iterator arg = arguments->begin(); arg != arguments->end(); arg++)
+ {
+ TIntermTyped *typedArg = (*arg)->getAsTyped();
+ if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(typedArg->getBasicType()))
+ {
+ out << "texture_";
+ (*arg)->traverse(this);
+ out << ", sampler_";
+ }
+
+ (*arg)->traverse(this);
+
+ if (typedArg->getType().isStructureContainingSamplers())
+ {
+ const TType &argType = typedArg->getType();
+ TVector<const TVariable *> samplerSymbols;
+ ImmutableString structName = samplerNamePrefixFromStruct(typedArg);
+ std::string namePrefix = "angle_";
+ namePrefix += structName.data();
+ argType.createSamplerSymbols(ImmutableString(namePrefix), "", &samplerSymbols,
+ nullptr, mSymbolTable);
+ for (const TVariable *sampler : samplerSymbols)
+ {
+ if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ out << ", texture_" << sampler->name();
+ out << ", sampler_" << sampler->name();
+ }
+ else
+ {
+ // In case of HLSL 4.1+, this symbol is the sampler index, and in case
+ // of D3D9, it's the sampler variable.
+ out << ", " << sampler->name();
+ }
+ }
+ }
+
+ if (arg < arguments->end() - 1)
+ {
+ out << ", ";
+ }
+ }
+
+ out << ")";
+
+ return false;
+ }
+ case EOpConstruct:
+ outputConstructor(out, visit, node);
+ break;
+ case EOpEqualComponentWise:
+ outputTriplet(out, visit, "(", " == ", ")");
+ break;
+ case EOpNotEqualComponentWise:
+ outputTriplet(out, visit, "(", " != ", ")");
+ break;
+ case EOpLessThanComponentWise:
+ outputTriplet(out, visit, "(", " < ", ")");
+ break;
+ case EOpGreaterThanComponentWise:
+ outputTriplet(out, visit, "(", " > ", ")");
+ break;
+ case EOpLessThanEqualComponentWise:
+ outputTriplet(out, visit, "(", " <= ", ")");
+ break;
+ case EOpGreaterThanEqualComponentWise:
+ outputTriplet(out, visit, "(", " >= ", ")");
+ break;
+ case EOpMod:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpModf:
+ outputTriplet(out, visit, "modf(", ", ", ")");
+ break;
+ case EOpPow:
+ outputTriplet(out, visit, "pow(", ", ", ")");
+ break;
+ case EOpAtan:
+ ASSERT(node->getSequence()->size() == 2); // atan(x) is a unary operator
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpMin:
+ outputTriplet(out, visit, "min(", ", ", ")");
+ break;
+ case EOpMax:
+ outputTriplet(out, visit, "max(", ", ", ")");
+ break;
+ case EOpClamp:
+ outputTriplet(out, visit, "clamp(", ", ", ")");
+ break;
+ case EOpMix:
+ {
+ TIntermTyped *lastParamNode = (*(node->getSequence()))[2]->getAsTyped();
+ if (lastParamNode->getType().getBasicType() == EbtBool)
+ {
+ // There is no HLSL equivalent for ESSL3 built-in "genType mix (genType x, genType
+ // y, genBType a)",
+ // so use emulated version.
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ }
+ else
+ {
+ outputTriplet(out, visit, "lerp(", ", ", ")");
+ }
+ break;
+ }
+ case EOpStep:
+ outputTriplet(out, visit, "step(", ", ", ")");
+ break;
+ case EOpSmoothstep:
+ outputTriplet(out, visit, "smoothstep(", ", ", ")");
+ break;
+ case EOpFma:
+ outputTriplet(out, visit, "mad(", ", ", ")");
+ break;
+ case EOpFrexp:
+ case EOpLdexp:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpDistance:
+ outputTriplet(out, visit, "distance(", ", ", ")");
+ break;
+ case EOpDot:
+ outputTriplet(out, visit, "dot(", ", ", ")");
+ break;
+ case EOpCross:
+ outputTriplet(out, visit, "cross(", ", ", ")");
+ break;
+ case EOpFaceforward:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpReflect:
+ outputTriplet(out, visit, "reflect(", ", ", ")");
+ break;
+ case EOpRefract:
+ outputTriplet(out, visit, "refract(", ", ", ")");
+ break;
+ case EOpOuterProduct:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpMatrixCompMult:
+ outputTriplet(out, visit, "(", " * ", ")");
+ break;
+ case EOpBitfieldExtract:
+ case EOpBitfieldInsert:
+ case EOpUaddCarry:
+ case EOpUsubBorrow:
+ case EOpUmulExtended:
+ case EOpImulExtended:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpDFdx:
+ if (mInsideDiscontinuousLoop || mOutputLod0Function)
+ {
+ outputTriplet(out, visit, "(", "", ", 0.0)");
+ }
+ else
+ {
+ outputTriplet(out, visit, "ddx(", "", ")");
+ }
+ break;
+ case EOpDFdy:
+ if (mInsideDiscontinuousLoop || mOutputLod0Function)
+ {
+ outputTriplet(out, visit, "(", "", ", 0.0)");
+ }
+ else
+ {
+ outputTriplet(out, visit, "ddy(", "", ")");
+ }
+ break;
+ case EOpFwidth:
+ if (mInsideDiscontinuousLoop || mOutputLod0Function)
+ {
+ outputTriplet(out, visit, "(", "", ", 0.0)");
+ }
+ else
+ {
+ outputTriplet(out, visit, "fwidth(", "", ")");
+ }
+ break;
+ case EOpBarrier:
+ // barrier() is translated to GroupMemoryBarrierWithGroupSync(), which is the
+ // cheapest *WithGroupSync() function, without any functionality loss, but
+ // with the potential for severe performance loss.
+ outputTriplet(out, visit, "GroupMemoryBarrierWithGroupSync(", "", ")");
+ break;
+ case EOpMemoryBarrierShared:
+ outputTriplet(out, visit, "GroupMemoryBarrier(", "", ")");
+ break;
+ case EOpMemoryBarrierAtomicCounter:
+ case EOpMemoryBarrierBuffer:
+ case EOpMemoryBarrierImage:
+ outputTriplet(out, visit, "DeviceMemoryBarrier(", "", ")");
+ break;
+ case EOpGroupMemoryBarrier:
+ case EOpMemoryBarrier:
+ outputTriplet(out, visit, "AllMemoryBarrier(", "", ")");
+ break;
+
+ // Single atomic function calls without return value.
+ // e.g. atomicAdd(dest, value) should be translated into InterlockedAdd(dest, value).
+ case EOpAtomicAdd:
+ case EOpAtomicMin:
+ case EOpAtomicMax:
+ case EOpAtomicAnd:
+ case EOpAtomicOr:
+ case EOpAtomicXor:
+ // The parameter 'original_value' of InterlockedExchange(dest, value, original_value)
+ // and InterlockedCompareExchange(dest, compare_value, value, original_value) is not
+ // optional.
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/interlockedexchange
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/interlockedcompareexchange
+ // So all the call of atomicExchange(dest, value) and atomicCompSwap(dest,
+ // compare_value, value) should all be modified into the form of "int temp; temp =
+ // atomicExchange(dest, value);" and "int temp; temp = atomicCompSwap(dest,
+ // compare_value, value);" in the intermediate tree before traversing outputHLSL.
+ case EOpAtomicExchange:
+ case EOpAtomicCompSwap:
+ {
+ ASSERT(node->getChildCount() > 1);
+ TIntermTyped *memNode = (*node->getSequence())[0]->getAsTyped();
+ if (IsInShaderStorageBlock(memNode))
+ {
+ // Atomic memory functions for SSBO.
+ // "_ssbo_atomicXXX_TYPE(RWByteAddressBuffer buffer, uint loc" is written to |out|.
+ mSSBOOutputHLSL->outputAtomicMemoryFunctionCallPrefix(memNode, node->getOp());
+ // Write the rest argument list to |out|.
+ for (size_t i = 1; i < node->getChildCount(); i++)
+ {
+ out << ", ";
+ TIntermTyped *argument = (*node->getSequence())[i]->getAsTyped();
+ if (IsInShaderStorageBlock(argument))
+ {
+ mSSBOOutputHLSL->outputLoadFunctionCall(argument);
+ }
+ else
+ {
+ argument->traverse(this);
+ }
+ }
+
+ out << ")";
+ return false;
+ }
+ else
+ {
+ // Atomic memory functions for shared variable.
+ if (node->getOp() != EOpAtomicExchange && node->getOp() != EOpAtomicCompSwap)
+ {
+ outputTriplet(out, visit,
+ GetHLSLAtomicFunctionStringAndLeftParenthesis(node->getOp()), ",",
+ ")");
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+
+ break;
+ }
+ }
+
+ return true;
+}
+
+void OutputHLSL::writeIfElse(TInfoSinkBase &out, TIntermIfElse *node)
+{
+ out << "if (";
+
+ node->getCondition()->traverse(this);
+
+ out << ")\n";
+
+ outputLineDirective(out, node->getLine().first_line);
+
+ bool discard = false;
+
+ if (node->getTrueBlock())
+ {
+ // The trueBlock child node will output braces.
+ node->getTrueBlock()->traverse(this);
+
+ // Detect true discard
+ discard = (discard || FindDiscard::search(node->getTrueBlock()));
+ }
+ else
+ {
+ // TODO(oetuaho): Check if the semicolon inside is necessary.
+ // It's there as a result of conservative refactoring of the output.
+ out << "{;}\n";
+ }
+
+ outputLineDirective(out, node->getLine().first_line);
+
+ if (node->getFalseBlock())
+ {
+ out << "else\n";
+
+ outputLineDirective(out, node->getFalseBlock()->getLine().first_line);
+
+ // The falseBlock child node will output braces.
+ node->getFalseBlock()->traverse(this);
+
+ outputLineDirective(out, node->getFalseBlock()->getLine().first_line);
+
+ // Detect false discard
+ discard = (discard || FindDiscard::search(node->getFalseBlock()));
+ }
+
+ // ANGLE issue 486: Detect problematic conditional discard
+ if (discard)
+ {
+ mUsesDiscardRewriting = true;
+ }
+}
+
+bool OutputHLSL::visitTernary(Visit, TIntermTernary *)
+{
+ // Ternary ops should have been already converted to something else in the AST. HLSL ternary
+ // operator doesn't short-circuit, so it's not the same as the GLSL ternary operator.
+ UNREACHABLE();
+ return false;
+}
+
+bool OutputHLSL::visitIfElse(Visit visit, TIntermIfElse *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ ASSERT(mInsideFunction);
+
+ // D3D errors when there is a gradient operation in a loop in an unflattened if.
+ if (mShaderType == GL_FRAGMENT_SHADER && mCurrentFunctionMetadata->hasGradientLoop(node))
+ {
+ out << "FLATTEN ";
+ }
+
+ writeIfElse(out, node);
+
+ return false;
+}
+
+bool OutputHLSL::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ ASSERT(node->getStatementList());
+ if (visit == PreVisit)
+ {
+ node->setStatementList(RemoveSwitchFallThrough(node->getStatementList(), mPerfDiagnostics));
+ }
+ outputTriplet(out, visit, "switch (", ") ", "");
+ // The curly braces get written when visiting the statementList block.
+ return true;
+}
+
+bool OutputHLSL::visitCase(Visit visit, TIntermCase *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ if (node->hasCondition())
+ {
+ outputTriplet(out, visit, "case (", "", "):\n");
+ return true;
+ }
+ else
+ {
+ out << "default:\n";
+ return false;
+ }
+}
+
+void OutputHLSL::visitConstantUnion(TIntermConstantUnion *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+ writeConstantUnion(out, node->getType(), node->getConstantValue());
+}
+
+bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
+{
+ mNestedLoopDepth++;
+
+ bool wasDiscontinuous = mInsideDiscontinuousLoop;
+ mInsideDiscontinuousLoop =
+ mInsideDiscontinuousLoop || mCurrentFunctionMetadata->mDiscontinuousLoops.count(node) > 0;
+
+ TInfoSinkBase &out = getInfoSink();
+
+ if (mOutputType == SH_HLSL_3_0_OUTPUT)
+ {
+ if (handleExcessiveLoop(out, node))
+ {
+ mInsideDiscontinuousLoop = wasDiscontinuous;
+ mNestedLoopDepth--;
+
+ return false;
+ }
+ }
+
+ const char *unroll = mCurrentFunctionMetadata->hasGradientInCallGraph(node) ? "LOOP" : "";
+ if (node->getType() == ELoopDoWhile)
+ {
+ out << "{" << unroll << " do\n";
+
+ outputLineDirective(out, node->getLine().first_line);
+ }
+ else
+ {
+ out << "{" << unroll << " for(";
+
+ if (node->getInit())
+ {
+ node->getInit()->traverse(this);
+ }
+
+ out << "; ";
+
+ if (node->getCondition())
+ {
+ node->getCondition()->traverse(this);
+ }
+
+ out << "; ";
+
+ if (node->getExpression())
+ {
+ node->getExpression()->traverse(this);
+ }
+
+ out << ")\n";
+
+ outputLineDirective(out, node->getLine().first_line);
+ }
+
+ if (node->getBody())
+ {
+ // The loop body node will output braces.
+ node->getBody()->traverse(this);
+ }
+ else
+ {
+ // TODO(oetuaho): Check if the semicolon inside is necessary.
+ // It's there as a result of conservative refactoring of the output.
+ out << "{;}\n";
+ }
+
+ outputLineDirective(out, node->getLine().first_line);
+
+ if (node->getType() == ELoopDoWhile)
+ {
+ outputLineDirective(out, node->getCondition()->getLine().first_line);
+ out << "while (";
+
+ node->getCondition()->traverse(this);
+
+ out << ");\n";
+ }
+
+ out << "}\n";
+
+ mInsideDiscontinuousLoop = wasDiscontinuous;
+ mNestedLoopDepth--;
+
+ return false;
+}
+
+bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node)
+{
+ if (visit == PreVisit)
+ {
+ TInfoSinkBase &out = getInfoSink();
+
+ switch (node->getFlowOp())
+ {
+ case EOpKill:
+ out << "discard";
+ break;
+ case EOpBreak:
+ if (mNestedLoopDepth > 1)
+ {
+ mUsesNestedBreak = true;
+ }
+
+ if (mExcessiveLoopIndex)
+ {
+ out << "{Break";
+ mExcessiveLoopIndex->traverse(this);
+ out << " = true; break;}\n";
+ }
+ else
+ {
+ out << "break";
+ }
+ break;
+ case EOpContinue:
+ out << "continue";
+ break;
+ case EOpReturn:
+ if (node->getExpression())
+ {
+ ASSERT(!mInsideMain);
+ out << "return ";
+ if (IsInShaderStorageBlock(node->getExpression()))
+ {
+ mSSBOOutputHLSL->outputLoadFunctionCall(node->getExpression());
+ return false;
+ }
+ }
+ else
+ {
+ if (mInsideMain && shaderNeedsGenerateOutput())
+ {
+ out << "return " << generateOutputCall();
+ }
+ else
+ {
+ out << "return";
+ }
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ return true;
+}
+
+// Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them
+// (The D3D documentation says 255 iterations, but the compiler complains at anything more than
+// 254).
+bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node)
+{
+ const int MAX_LOOP_ITERATIONS = 254;
+
+ // Parse loops of the form:
+ // for(int index = initial; index [comparator] limit; index += increment)
+ TIntermSymbol *index = nullptr;
+ TOperator comparator = EOpNull;
+ int initial = 0;
+ int limit = 0;
+ int increment = 0;
+
+ // Parse index name and intial value
+ if (node->getInit())
+ {
+ TIntermDeclaration *init = node->getInit()->getAsDeclarationNode();
+
+ if (init)
+ {
+ TIntermSequence *sequence = init->getSequence();
+ TIntermTyped *variable = (*sequence)[0]->getAsTyped();
+
+ if (variable && variable->getQualifier() == EvqTemporary)
+ {
+ TIntermBinary *assign = variable->getAsBinaryNode();
+
+ if (assign != nullptr && assign->getOp() == EOpInitialize)
+ {
+ TIntermSymbol *symbol = assign->getLeft()->getAsSymbolNode();
+ TIntermConstantUnion *constant = assign->getRight()->getAsConstantUnion();
+
+ if (symbol && constant)
+ {
+ if (constant->getBasicType() == EbtInt && constant->isScalar())
+ {
+ index = symbol;
+ initial = constant->getIConst(0);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Parse comparator and limit value
+ if (index != nullptr && node->getCondition())
+ {
+ TIntermBinary *test = node->getCondition()->getAsBinaryNode();
+
+ if (test && test->getLeft()->getAsSymbolNode()->uniqueId() == index->uniqueId())
+ {
+ TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion();
+
+ if (constant)
+ {
+ if (constant->getBasicType() == EbtInt && constant->isScalar())
+ {
+ comparator = test->getOp();
+ limit = constant->getIConst(0);
+ }
+ }
+ }
+ }
+
+ // Parse increment
+ if (index != nullptr && comparator != EOpNull && node->getExpression())
+ {
+ TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode();
+ TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode();
+
+ if (binaryTerminal)
+ {
+ TOperator op = binaryTerminal->getOp();
+ TIntermConstantUnion *constant = binaryTerminal->getRight()->getAsConstantUnion();
+
+ if (constant)
+ {
+ if (constant->getBasicType() == EbtInt && constant->isScalar())
+ {
+ int value = constant->getIConst(0);
+
+ switch (op)
+ {
+ case EOpAddAssign:
+ increment = value;
+ break;
+ case EOpSubAssign:
+ increment = -value;
+ break;
+ default:
+ UNIMPLEMENTED();
+ }
+ }
+ }
+ }
+ else if (unaryTerminal)
+ {
+ TOperator op = unaryTerminal->getOp();
+
+ switch (op)
+ {
+ case EOpPostIncrement:
+ increment = 1;
+ break;
+ case EOpPostDecrement:
+ increment = -1;
+ break;
+ case EOpPreIncrement:
+ increment = 1;
+ break;
+ case EOpPreDecrement:
+ increment = -1;
+ break;
+ default:
+ UNIMPLEMENTED();
+ }
+ }
+ }
+
+ if (index != nullptr && comparator != EOpNull && increment != 0)
+ {
+ if (comparator == EOpLessThanEqual)
+ {
+ comparator = EOpLessThan;
+ limit += 1;
+ }
+
+ if (comparator == EOpLessThan)
+ {
+ int iterations = (limit - initial) / increment;
+
+ if (iterations <= MAX_LOOP_ITERATIONS)
+ {
+ return false; // Not an excessive loop
+ }
+
+ TIntermSymbol *restoreIndex = mExcessiveLoopIndex;
+ mExcessiveLoopIndex = index;
+
+ out << "{int ";
+ index->traverse(this);
+ out << ";\n"
+ "bool Break";
+ index->traverse(this);
+ out << " = false;\n";
+
+ bool firstLoopFragment = true;
+
+ while (iterations > 0)
+ {
+ int clampedLimit = initial + increment * std::min(MAX_LOOP_ITERATIONS, iterations);
+
+ if (!firstLoopFragment)
+ {
+ out << "if (!Break";
+ index->traverse(this);
+ out << ") {\n";
+ }
+
+ if (iterations <= MAX_LOOP_ITERATIONS) // Last loop fragment
+ {
+ mExcessiveLoopIndex = nullptr; // Stops setting the Break flag
+ }
+
+ // for(int index = initial; index < clampedLimit; index += increment)
+ const char *unroll =
+ mCurrentFunctionMetadata->hasGradientInCallGraph(node) ? "LOOP" : "";
+
+ out << unroll << " for(";
+ index->traverse(this);
+ out << " = ";
+ out << initial;
+
+ out << "; ";
+ index->traverse(this);
+ out << " < ";
+ out << clampedLimit;
+
+ out << "; ";
+ index->traverse(this);
+ out << " += ";
+ out << increment;
+ out << ")\n";
+
+ outputLineDirective(out, node->getLine().first_line);
+ out << "{\n";
+
+ if (node->getBody())
+ {
+ node->getBody()->traverse(this);
+ }
+
+ outputLineDirective(out, node->getLine().first_line);
+ out << ";}\n";
+
+ if (!firstLoopFragment)
+ {
+ out << "}\n";
+ }
+
+ firstLoopFragment = false;
+
+ initial += MAX_LOOP_ITERATIONS * increment;
+ iterations -= MAX_LOOP_ITERATIONS;
+ }
+
+ out << "}";
+
+ mExcessiveLoopIndex = restoreIndex;
+
+ return true;
+ }
+ else
+ UNIMPLEMENTED();
+ }
+
+ return false; // Not handled as an excessive loop
+}
+
+void OutputHLSL::outputTriplet(TInfoSinkBase &out,
+ Visit visit,
+ const char *preString,
+ const char *inString,
+ const char *postString)
+{
+ if (visit == PreVisit)
+ {
+ out << preString;
+ }
+ else if (visit == InVisit)
+ {
+ out << inString;
+ }
+ else if (visit == PostVisit)
+ {
+ out << postString;
+ }
+}
+
+void OutputHLSL::outputLineDirective(TInfoSinkBase &out, int line)
+{
+ if (mCompileOptions.lineDirectives && line > 0)
+ {
+ out << "\n";
+ out << "#line " << line;
+
+ if (mSourcePath)
+ {
+ out << " \"" << mSourcePath << "\"";
+ }
+
+ out << "\n";
+ }
+}
+
+void OutputHLSL::writeParameter(const TVariable *param, TInfoSinkBase &out)
+{
+ const TType &type = param->getType();
+ TQualifier qualifier = type.getQualifier();
+
+ TString nameStr = DecorateVariableIfNeeded(*param);
+ ASSERT(nameStr != ""); // HLSL demands named arguments, also for prototypes
+
+ if (IsSampler(type.getBasicType()))
+ {
+ if (mOutputType == SH_HLSL_4_1_OUTPUT)
+ {
+ // Samplers are passed as indices to the sampler array.
+ ASSERT(qualifier != EvqParamOut && qualifier != EvqParamInOut);
+ out << "const uint " << nameStr << ArrayString(type);
+ return;
+ }
+ if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ out << QualifierString(qualifier) << " " << TextureString(type.getBasicType())
+ << " texture_" << nameStr << ArrayString(type) << ", " << QualifierString(qualifier)
+ << " " << SamplerString(type.getBasicType()) << " sampler_" << nameStr
+ << ArrayString(type);
+ return;
+ }
+ }
+
+ // If the parameter is an atomic counter, we need to add an extra parameter to keep track of the
+ // buffer offset.
+ if (IsAtomicCounter(type.getBasicType()))
+ {
+ out << QualifierString(qualifier) << " " << TypeString(type) << " " << nameStr << ", int "
+ << nameStr << "_offset";
+ }
+ else
+ {
+ out << QualifierString(qualifier) << " " << TypeString(type) << " " << nameStr
+ << ArrayString(type);
+ }
+
+ // If the structure parameter contains samplers, they need to be passed into the function as
+ // separate parameters. HLSL doesn't natively support samplers in structs.
+ if (type.isStructureContainingSamplers())
+ {
+ ASSERT(qualifier != EvqParamOut && qualifier != EvqParamInOut);
+ TVector<const TVariable *> samplerSymbols;
+ std::string namePrefix = "angle";
+ namePrefix += nameStr.c_str();
+ type.createSamplerSymbols(ImmutableString(namePrefix), "", &samplerSymbols, nullptr,
+ mSymbolTable);
+ for (const TVariable *sampler : samplerSymbols)
+ {
+ const TType &samplerType = sampler->getType();
+ if (mOutputType == SH_HLSL_4_1_OUTPUT)
+ {
+ out << ", const uint " << sampler->name() << ArrayString(samplerType);
+ }
+ else if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ ASSERT(IsSampler(samplerType.getBasicType()));
+ out << ", " << QualifierString(qualifier) << " "
+ << TextureString(samplerType.getBasicType()) << " texture_" << sampler->name()
+ << ArrayString(samplerType) << ", " << QualifierString(qualifier) << " "
+ << SamplerString(samplerType.getBasicType()) << " sampler_" << sampler->name()
+ << ArrayString(samplerType);
+ }
+ else
+ {
+ ASSERT(IsSampler(samplerType.getBasicType()));
+ out << ", " << QualifierString(qualifier) << " " << TypeString(samplerType) << " "
+ << sampler->name() << ArrayString(samplerType);
+ }
+ }
+ }
+}
+
+TString OutputHLSL::zeroInitializer(const TType &type) const
+{
+ TString string;
+
+ size_t size = type.getObjectSize();
+ if (size >= kZeroCount)
+ {
+ mUseZeroArray = true;
+ }
+ string = GetZeroInitializer(size).c_str();
+
+ return "{" + string + "}";
+}
+
+void OutputHLSL::outputConstructor(TInfoSinkBase &out, Visit visit, TIntermAggregate *node)
+{
+ // Array constructors should have been already pruned from the code.
+ ASSERT(!node->getType().isArray());
+
+ if (visit == PreVisit)
+ {
+ TString constructorName;
+ if (node->getBasicType() == EbtStruct)
+ {
+ constructorName = mStructureHLSL->addStructConstructor(*node->getType().getStruct());
+ }
+ else
+ {
+ constructorName =
+ mStructureHLSL->addBuiltInConstructor(node->getType(), node->getSequence());
+ }
+ out << constructorName << "(";
+ }
+ else if (visit == InVisit)
+ {
+ out << ", ";
+ }
+ else if (visit == PostVisit)
+ {
+ out << ")";
+ }
+}
+
+const TConstantUnion *OutputHLSL::writeConstantUnion(TInfoSinkBase &out,
+ const TType &type,
+ const TConstantUnion *const constUnion)
+{
+ ASSERT(!type.isArray());
+
+ const TConstantUnion *constUnionIterated = constUnion;
+
+ const TStructure *structure = type.getStruct();
+ if (structure)
+ {
+ out << mStructureHLSL->addStructConstructor(*structure) << "(";
+
+ const TFieldList &fields = structure->fields();
+
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ const TType *fieldType = fields[i]->type();
+ constUnionIterated = writeConstantUnion(out, *fieldType, constUnionIterated);
+
+ if (i != fields.size() - 1)
+ {
+ out << ", ";
+ }
+ }
+
+ out << ")";
+ }
+ else
+ {
+ size_t size = type.getObjectSize();
+ bool writeType = size > 1;
+
+ if (writeType)
+ {
+ out << TypeString(type) << "(";
+ }
+ constUnionIterated = writeConstantUnionArray(out, constUnionIterated, size);
+ if (writeType)
+ {
+ out << ")";
+ }
+ }
+
+ return constUnionIterated;
+}
+
+void OutputHLSL::writeEmulatedFunctionTriplet(TInfoSinkBase &out,
+ Visit visit,
+ const TFunction *function)
+{
+ if (visit == PreVisit)
+ {
+ ASSERT(function != nullptr);
+ BuiltInFunctionEmulator::WriteEmulatedFunctionName(out, function->name().data());
+ out << "(";
+ }
+ else
+ {
+ outputTriplet(out, visit, nullptr, ", ", ")");
+ }
+}
+
+bool OutputHLSL::writeSameSymbolInitializer(TInfoSinkBase &out,
+ TIntermSymbol *symbolNode,
+ TIntermTyped *expression)
+{
+ ASSERT(symbolNode->variable().symbolType() != SymbolType::Empty);
+ const TIntermSymbol *symbolInInitializer = FindSymbolNode(expression, symbolNode->getName());
+
+ if (symbolInInitializer)
+ {
+ // Type already printed
+ out << "t" + str(mUniqueIndex) + " = ";
+ expression->traverse(this);
+ out << ", ";
+ symbolNode->traverse(this);
+ out << " = t" + str(mUniqueIndex);
+
+ mUniqueIndex++;
+ return true;
+ }
+
+ return false;
+}
+
+bool OutputHLSL::writeConstantInitialization(TInfoSinkBase &out,
+ TIntermSymbol *symbolNode,
+ TIntermTyped *initializer)
+{
+ if (initializer->hasConstantValue())
+ {
+ symbolNode->traverse(this);
+ out << ArrayString(symbolNode->getType());
+ out << " = {";
+ writeConstantUnionArray(out, initializer->getConstantValue(),
+ initializer->getType().getObjectSize());
+ out << "}";
+ return true;
+ }
+ return false;
+}
+
+TString OutputHLSL::addStructEqualityFunction(const TStructure &structure)
+{
+ const TFieldList &fields = structure.fields();
+
+ for (const auto &eqFunction : mStructEqualityFunctions)
+ {
+ if (eqFunction->structure == &structure)
+ {
+ return eqFunction->functionName;
+ }
+ }
+
+ const TString &structNameString = StructNameString(structure);
+
+ StructEqualityFunction *function = new StructEqualityFunction();
+ function->structure = &structure;
+ function->functionName = "angle_eq_" + structNameString;
+
+ TInfoSinkBase fnOut;
+
+ fnOut << "bool " << function->functionName << "(" << structNameString << " a, "
+ << structNameString + " b)\n"
+ << "{\n"
+ " return ";
+
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ const TField *field = fields[i];
+ const TType *fieldType = field->type();
+
+ const TString &fieldNameA = "a." + Decorate(field->name());
+ const TString &fieldNameB = "b." + Decorate(field->name());
+
+ if (i > 0)
+ {
+ fnOut << " && ";
+ }
+
+ fnOut << "(";
+ outputEqual(PreVisit, *fieldType, EOpEqual, fnOut);
+ fnOut << fieldNameA;
+ outputEqual(InVisit, *fieldType, EOpEqual, fnOut);
+ fnOut << fieldNameB;
+ outputEqual(PostVisit, *fieldType, EOpEqual, fnOut);
+ fnOut << ")";
+ }
+
+ fnOut << ";\n"
+ << "}\n";
+
+ function->functionDefinition = fnOut.c_str();
+
+ mStructEqualityFunctions.push_back(function);
+ mEqualityFunctions.push_back(function);
+
+ return function->functionName;
+}
+
+TString OutputHLSL::addArrayEqualityFunction(const TType &type)
+{
+ for (const auto &eqFunction : mArrayEqualityFunctions)
+ {
+ if (eqFunction->type == type)
+ {
+ return eqFunction->functionName;
+ }
+ }
+
+ TType elementType(type);
+ elementType.toArrayElementType();
+
+ ArrayHelperFunction *function = new ArrayHelperFunction();
+ function->type = type;
+
+ function->functionName = ArrayHelperFunctionName("angle_eq", type);
+
+ TInfoSinkBase fnOut;
+
+ const TString &typeName = TypeString(type);
+ fnOut << "bool " << function->functionName << "(" << typeName << " a" << ArrayString(type)
+ << ", " << typeName << " b" << ArrayString(type) << ")\n"
+ << "{\n"
+ " for (int i = 0; i < "
+ << type.getOutermostArraySize()
+ << "; ++i)\n"
+ " {\n"
+ " if (";
+
+ outputEqual(PreVisit, elementType, EOpNotEqual, fnOut);
+ fnOut << "a[i]";
+ outputEqual(InVisit, elementType, EOpNotEqual, fnOut);
+ fnOut << "b[i]";
+ outputEqual(PostVisit, elementType, EOpNotEqual, fnOut);
+
+ fnOut << ") { return false; }\n"
+ " }\n"
+ " return true;\n"
+ "}\n";
+
+ function->functionDefinition = fnOut.c_str();
+
+ mArrayEqualityFunctions.push_back(function);
+ mEqualityFunctions.push_back(function);
+
+ return function->functionName;
+}
+
+TString OutputHLSL::addArrayAssignmentFunction(const TType &type)
+{
+ for (const auto &assignFunction : mArrayAssignmentFunctions)
+ {
+ if (assignFunction.type == type)
+ {
+ return assignFunction.functionName;
+ }
+ }
+
+ TType elementType(type);
+ elementType.toArrayElementType();
+
+ ArrayHelperFunction function;
+ function.type = type;
+
+ function.functionName = ArrayHelperFunctionName("angle_assign", type);
+
+ TInfoSinkBase fnOut;
+
+ const TString &typeName = TypeString(type);
+ fnOut << "void " << function.functionName << "(out " << typeName << " a" << ArrayString(type)
+ << ", " << typeName << " b" << ArrayString(type) << ")\n"
+ << "{\n"
+ " for (int i = 0; i < "
+ << type.getOutermostArraySize()
+ << "; ++i)\n"
+ " {\n"
+ " ";
+
+ outputAssign(PreVisit, elementType, fnOut);
+ fnOut << "a[i]";
+ outputAssign(InVisit, elementType, fnOut);
+ fnOut << "b[i]";
+ outputAssign(PostVisit, elementType, fnOut);
+
+ fnOut << ";\n"
+ " }\n"
+ "}\n";
+
+ function.functionDefinition = fnOut.c_str();
+
+ mArrayAssignmentFunctions.push_back(function);
+
+ return function.functionName;
+}
+
+TString OutputHLSL::addArrayConstructIntoFunction(const TType &type)
+{
+ for (const auto &constructIntoFunction : mArrayConstructIntoFunctions)
+ {
+ if (constructIntoFunction.type == type)
+ {
+ return constructIntoFunction.functionName;
+ }
+ }
+
+ TType elementType(type);
+ elementType.toArrayElementType();
+
+ ArrayHelperFunction function;
+ function.type = type;
+
+ function.functionName = ArrayHelperFunctionName("angle_construct_into", type);
+
+ TInfoSinkBase fnOut;
+
+ const TString &typeName = TypeString(type);
+ fnOut << "void " << function.functionName << "(out " << typeName << " a" << ArrayString(type);
+ for (unsigned int i = 0u; i < type.getOutermostArraySize(); ++i)
+ {
+ fnOut << ", " << typeName << " b" << i << ArrayString(elementType);
+ }
+ fnOut << ")\n"
+ "{\n";
+
+ for (unsigned int i = 0u; i < type.getOutermostArraySize(); ++i)
+ {
+ fnOut << " ";
+ outputAssign(PreVisit, elementType, fnOut);
+ fnOut << "a[" << i << "]";
+ outputAssign(InVisit, elementType, fnOut);
+ fnOut << "b" << i;
+ outputAssign(PostVisit, elementType, fnOut);
+ fnOut << ";\n";
+ }
+ fnOut << "}\n";
+
+ function.functionDefinition = fnOut.c_str();
+
+ mArrayConstructIntoFunctions.push_back(function);
+
+ return function.functionName;
+}
+
+void OutputHLSL::ensureStructDefined(const TType &type)
+{
+ const TStructure *structure = type.getStruct();
+ if (structure)
+ {
+ ASSERT(type.getBasicType() == EbtStruct);
+ mStructureHLSL->ensureStructDefined(*structure);
+ }
+}
+
+bool OutputHLSL::shaderNeedsGenerateOutput() const
+{
+ return mShaderType == GL_VERTEX_SHADER || mShaderType == GL_FRAGMENT_SHADER;
+}
+
+const char *OutputHLSL::generateOutputCall() const
+{
+ if (mShaderType == GL_VERTEX_SHADER)
+ {
+ return "generateOutput(input)";
+ }
+ else
+ {
+ return "generateOutput()";
+ }
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputHLSL.h b/gfx/angle/checkout/src/compiler/translator/OutputHLSL.h
new file mode 100644
index 0000000000..06cc22d486
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputHLSL.h
@@ -0,0 +1,289 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_OUTPUTHLSL_H_
+#define COMPILER_TRANSLATOR_OUTPUTHLSL_H_
+
+#include <list>
+#include <map>
+#include <stack>
+
+#include "angle_gl.h"
+#include "compiler/translator/ASTMetadataHLSL.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/FlagStd140Structs.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/ShaderStorageBlockOutputHLSL.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+class BuiltInFunctionEmulator;
+
+namespace sh
+{
+class AtomicCounterFunctionHLSL;
+class ImageFunctionHLSL;
+class ResourcesHLSL;
+class StructureHLSL;
+class TextureFunctionHLSL;
+class TSymbolTable;
+class TVariable;
+class UnfoldShortCircuit;
+
+using ReferencedVariables = std::map<int, const TVariable *>;
+
+class OutputHLSL : public TIntermTraverser
+{
+ public:
+ OutputHLSL(sh::GLenum shaderType,
+ ShShaderSpec shaderSpec,
+ int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ const char *sourcePath,
+ ShShaderOutput outputType,
+ int numRenderTargets,
+ int maxDualSourceDrawBuffers,
+ const std::vector<ShaderVariable> &uniforms,
+ const ShCompileOptions &compileOptions,
+ sh::WorkGroupSize workGroupSize,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics,
+ const std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap,
+ const std::vector<InterfaceBlock> &shaderStorageBlocks,
+ bool isEarlyFragmentTestsSpecified);
+
+ ~OutputHLSL() override;
+
+ void output(TIntermNode *treeRoot, TInfoSinkBase &objSink);
+
+ const std::map<std::string, unsigned int> &getShaderStorageBlockRegisterMap() const;
+ const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const;
+ const std::map<std::string, bool> &getUniformBlockUseStructuredBufferMap() const;
+ const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
+ unsigned int getReadonlyImage2DRegisterIndex() const;
+ unsigned int getImage2DRegisterIndex() const;
+ const std::set<std::string> &getUsedImage2DFunctionNames() const;
+
+ TInfoSinkBase &getInfoSink()
+ {
+ ASSERT(!mInfoSinkStack.empty());
+ return *mInfoSinkStack.top();
+ }
+
+ protected:
+ friend class ShaderStorageBlockOutputHLSL;
+
+ TString zeroInitializer(const TType &type) const;
+
+ void writeReferencedAttributes(TInfoSinkBase &out) const;
+ void writeReferencedVaryings(TInfoSinkBase &out) const;
+ void header(TInfoSinkBase &out,
+ const std::vector<MappedStruct> &std140Structs,
+ const BuiltInFunctionEmulator *builtInFunctionEmulator) const;
+
+ void writeFloat(TInfoSinkBase &out, float f);
+ void writeSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion);
+ const TConstantUnion *writeConstantUnionArray(TInfoSinkBase &out,
+ const TConstantUnion *const constUnion,
+ const size_t size);
+
+ // Visit AST nodes and output their code to the body stream
+ void visitSymbol(TIntermSymbol *) override;
+ void visitConstantUnion(TIntermConstantUnion *) override;
+ bool visitSwizzle(Visit visit, TIntermSwizzle *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *) override;
+ bool visitUnary(Visit visit, TIntermUnary *) override;
+ bool visitTernary(Visit visit, TIntermTernary *) override;
+ bool visitIfElse(Visit visit, TIntermIfElse *) override;
+ bool visitSwitch(Visit visit, TIntermSwitch *) override;
+ bool visitCase(Visit visit, TIntermCase *) override;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitLoop(Visit visit, TIntermLoop *) override;
+ bool visitBranch(Visit visit, TIntermBranch *) override;
+
+ bool handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node);
+
+ // Emit one of three strings depending on traverse phase. Called with literal strings so using
+ // const char* instead of TString.
+ void outputTriplet(TInfoSinkBase &out,
+ Visit visit,
+ const char *preString,
+ const char *inString,
+ const char *postString);
+ void outputLineDirective(TInfoSinkBase &out, int line);
+ void writeParameter(const TVariable *param, TInfoSinkBase &out);
+
+ void outputConstructor(TInfoSinkBase &out, Visit visit, TIntermAggregate *node);
+ const TConstantUnion *writeConstantUnion(TInfoSinkBase &out,
+ const TType &type,
+ const TConstantUnion *constUnion);
+
+ void outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out);
+ void outputAssign(Visit visit, const TType &type, TInfoSinkBase &out);
+
+ void writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, const TFunction *function);
+
+ // Returns true if it found a 'same symbol' initializer (initializer that references the
+ // variable it's initting)
+ bool writeSameSymbolInitializer(TInfoSinkBase &out,
+ TIntermSymbol *symbolNode,
+ TIntermTyped *expression);
+ // Returns true if variable initializer could be written using literal {} notation.
+ bool writeConstantInitialization(TInfoSinkBase &out,
+ TIntermSymbol *symbolNode,
+ TIntermTyped *expression);
+
+ void writeIfElse(TInfoSinkBase &out, TIntermIfElse *node);
+
+ // Returns the function name
+ TString addStructEqualityFunction(const TStructure &structure);
+ TString addArrayEqualityFunction(const TType &type);
+ TString addArrayAssignmentFunction(const TType &type);
+ TString addArrayConstructIntoFunction(const TType &type);
+
+ // Ensures if the type is a struct, the struct is defined
+ void ensureStructDefined(const TType &type);
+
+ bool shaderNeedsGenerateOutput() const;
+ const char *generateOutputCall() const;
+
+ sh::GLenum mShaderType;
+ ShShaderSpec mShaderSpec;
+ int mShaderVersion;
+ const TExtensionBehavior &mExtensionBehavior;
+ const char *mSourcePath;
+ const ShShaderOutput mOutputType;
+ const ShCompileOptions &mCompileOptions;
+
+ bool mInsideFunction;
+ bool mInsideMain;
+
+ // Output streams
+ TInfoSinkBase mHeader;
+ TInfoSinkBase mBody;
+ TInfoSinkBase mFooter;
+
+ // A stack is useful when we want to traverse in the header, or in helper functions, but not
+ // always write to the body. Instead use an InfoSink stack to keep our current state intact.
+ // TODO (jmadill): Just passing an InfoSink in function parameters would be simpler.
+ std::stack<TInfoSinkBase *> mInfoSinkStack;
+
+ ReferencedVariables mReferencedUniforms;
+
+ // Indexed by block id, not instance id.
+ ReferencedInterfaceBlocks mReferencedUniformBlocks;
+
+ std::map<int, const TInterfaceBlock *> mUniformBlockOptimizedMap;
+
+ ReferencedVariables mReferencedAttributes;
+ ReferencedVariables mReferencedVaryings;
+ ReferencedVariables mReferencedOutputVariables;
+
+ StructureHLSL *mStructureHLSL;
+ ResourcesHLSL *mResourcesHLSL;
+ TextureFunctionHLSL *mTextureFunctionHLSL;
+ ImageFunctionHLSL *mImageFunctionHLSL;
+ AtomicCounterFunctionHLSL *mAtomicCounterFunctionHLSL;
+
+ // Parameters determining what goes in the header output
+ bool mUsesFragColor;
+ bool mUsesFragData;
+ bool mUsesDepthRange;
+ bool mUsesFragCoord;
+ bool mUsesPointCoord;
+ bool mUsesFrontFacing;
+ bool mUsesHelperInvocation;
+ bool mUsesPointSize;
+ bool mUsesInstanceID;
+ bool mHasMultiviewExtensionEnabled;
+ bool mUsesViewID;
+ bool mUsesVertexID;
+ bool mUsesFragDepth;
+ bool mUsesNumWorkGroups;
+ bool mUsesWorkGroupID;
+ bool mUsesLocalInvocationID;
+ bool mUsesGlobalInvocationID;
+ bool mUsesLocalInvocationIndex;
+ bool mUsesXor;
+ bool mUsesDiscardRewriting;
+ bool mUsesNestedBreak;
+ bool mRequiresIEEEStrictCompiling;
+ mutable bool mUseZeroArray;
+ bool mUsesSecondaryColor;
+
+ int mNumRenderTargets;
+ int mMaxDualSourceDrawBuffers;
+
+ int mUniqueIndex; // For creating unique names
+
+ CallDAG mCallDag;
+ MetadataList mASTMetadataList;
+ ASTMetadataHLSL *mCurrentFunctionMetadata;
+ bool mOutputLod0Function;
+ bool mInsideDiscontinuousLoop;
+ int mNestedLoopDepth;
+
+ TIntermSymbol *mExcessiveLoopIndex;
+
+ TString structInitializerString(int indent, const TType &type, const TString &name) const;
+
+ struct HelperFunction
+ {
+ TString functionName;
+ TString functionDefinition;
+
+ virtual ~HelperFunction() {}
+ };
+
+ // A list of all equality comparison functions. It's important to preserve the order at
+ // which we add the functions, since nested structures call each other recursively, and
+ // structure equality functions may need to call array equality functions and vice versa.
+ // The ownership of the pointers is maintained by the type-specific arrays.
+ std::vector<HelperFunction *> mEqualityFunctions;
+
+ struct StructEqualityFunction : public HelperFunction
+ {
+ const TStructure *structure;
+ };
+ std::vector<StructEqualityFunction *> mStructEqualityFunctions;
+
+ struct ArrayHelperFunction : public HelperFunction
+ {
+ TType type;
+ };
+ std::vector<ArrayHelperFunction *> mArrayEqualityFunctions;
+
+ std::vector<ArrayHelperFunction> mArrayAssignmentFunctions;
+
+ // The construct-into functions are functions that fill an N-element array passed as an out
+ // parameter with the other N parameters of the function. This is used to work around that
+ // arrays can't be return values in HLSL.
+ std::vector<ArrayHelperFunction> mArrayConstructIntoFunctions;
+
+ sh::WorkGroupSize mWorkGroupSize;
+
+ PerformanceDiagnostics *mPerfDiagnostics;
+
+ private:
+ TString generateStructMapping(const std::vector<MappedStruct> &std140Structs) const;
+ ImmutableString samplerNamePrefixFromStruct(TIntermTyped *node);
+ bool ancestorEvaluatesToSamplerInStruct();
+ // We need to do struct mapping when pass the struct to a function or copy the struct via
+ // assignment.
+ bool needStructMapping(TIntermTyped *node);
+
+ ShaderStorageBlockOutputHLSL *mSSBOOutputHLSL;
+ bool mIsEarlyFragmentTestsSpecified;
+ bool mNeedStructMapping;
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OUTPUTHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputTree.cpp b/gfx/angle/checkout/src/compiler/translator/OutputTree.cpp
new file mode 100644
index 0000000000..f51e891ce8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputTree.cpp
@@ -0,0 +1,723 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void OutputFunction(TInfoSinkBase &out, const char *str, const TFunction *func)
+{
+ const char *internal =
+ (func->symbolType() == SymbolType::AngleInternal) ? " (internal function)" : "";
+ out << str << internal << ": " << func->name() << " (symbol id " << func->uniqueId().get()
+ << ")";
+}
+
+// Two purposes:
+// 1. Show an example of how to iterate tree. Functions can also directly call traverse() on
+// children themselves to have finer grained control over the process than shown here, though
+// that's not recommended if it can be avoided.
+// 2. Print out a text based description of the tree.
+
+// The traverser subclass is used to carry along data from node to node in the traversal.
+class TOutputTraverser : public TIntermTraverser
+{
+ public:
+ TOutputTraverser(TInfoSinkBase &out)
+ : TIntermTraverser(true, false, false), mOut(out), mIndentDepth(0)
+ {}
+
+ protected:
+ void visitSymbol(TIntermSymbol *) override;
+ void visitConstantUnion(TIntermConstantUnion *) override;
+ bool visitSwizzle(Visit visit, TIntermSwizzle *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *) override;
+ bool visitUnary(Visit visit, TIntermUnary *) override;
+ bool visitTernary(Visit visit, TIntermTernary *node) override;
+ bool visitIfElse(Visit visit, TIntermIfElse *node) override;
+ bool visitSwitch(Visit visit, TIntermSwitch *node) override;
+ bool visitCase(Visit visit, TIntermCase *node) override;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *) override;
+ bool visitBlock(Visit visit, TIntermBlock *) override;
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitLoop(Visit visit, TIntermLoop *) override;
+ bool visitBranch(Visit visit, TIntermBranch *) override;
+
+ int getCurrentIndentDepth() const { return mIndentDepth + getCurrentTraversalDepth(); }
+
+ TInfoSinkBase &mOut;
+ int mIndentDepth;
+};
+
+//
+// Helper functions for printing, not part of traversing.
+//
+void OutputTreeText(TInfoSinkBase &out, TIntermNode *node, const int depth)
+{
+ int i;
+
+ out.location(node->getLine().first_file, node->getLine().first_line);
+
+ for (i = 0; i < depth; ++i)
+ out << " ";
+}
+
+//
+// The rest of the file are the traversal functions. The last one
+// is the one that starts the traversal.
+//
+// Return true from interior nodes to have the external traversal
+// continue on to children. If you process children yourself,
+// return false.
+//
+
+void TOutputTraverser::visitSymbol(TIntermSymbol *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ if (node->variable().symbolType() == SymbolType::Empty)
+ {
+ mOut << "''";
+ }
+ else
+ {
+ mOut << "'" << node->getName() << "' ";
+ }
+ mOut << "(symbol id " << node->uniqueId().get() << ") ";
+ mOut << "(" << node->getType() << ")";
+ mOut << "\n";
+}
+
+bool TOutputTraverser::visitSwizzle(Visit visit, TIntermSwizzle *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "vector swizzle (";
+ node->writeOffsetsAsXYZW(&mOut);
+ mOut << ")";
+
+ mOut << " (" << node->getType() << ")";
+ mOut << "\n";
+ return true;
+}
+
+bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ switch (node->getOp())
+ {
+ case EOpComma:
+ mOut << "comma";
+ break;
+ case EOpAssign:
+ mOut << "move second child to first child";
+ break;
+ case EOpInitialize:
+ mOut << "initialize first child with second child";
+ break;
+ case EOpAddAssign:
+ mOut << "add second child into first child";
+ break;
+ case EOpSubAssign:
+ mOut << "subtract second child into first child";
+ break;
+ case EOpMulAssign:
+ mOut << "multiply second child into first child";
+ break;
+ case EOpVectorTimesMatrixAssign:
+ mOut << "matrix mult second child into first child";
+ break;
+ case EOpVectorTimesScalarAssign:
+ mOut << "vector scale second child into first child";
+ break;
+ case EOpMatrixTimesScalarAssign:
+ mOut << "matrix scale second child into first child";
+ break;
+ case EOpMatrixTimesMatrixAssign:
+ mOut << "matrix mult second child into first child";
+ break;
+ case EOpDivAssign:
+ mOut << "divide second child into first child";
+ break;
+ case EOpIModAssign:
+ mOut << "modulo second child into first child";
+ break;
+ case EOpBitShiftLeftAssign:
+ mOut << "bit-wise shift first child left by second child";
+ break;
+ case EOpBitShiftRightAssign:
+ mOut << "bit-wise shift first child right by second child";
+ break;
+ case EOpBitwiseAndAssign:
+ mOut << "bit-wise and second child into first child";
+ break;
+ case EOpBitwiseXorAssign:
+ mOut << "bit-wise xor second child into first child";
+ break;
+ case EOpBitwiseOrAssign:
+ mOut << "bit-wise or second child into first child";
+ break;
+
+ case EOpIndexDirect:
+ mOut << "direct index";
+ break;
+ case EOpIndexIndirect:
+ mOut << "indirect index";
+ break;
+ case EOpIndexDirectStruct:
+ mOut << "direct index for structure";
+ break;
+ case EOpIndexDirectInterfaceBlock:
+ mOut << "direct index for interface block";
+ break;
+
+ case EOpAdd:
+ mOut << "add";
+ break;
+ case EOpSub:
+ mOut << "subtract";
+ break;
+ case EOpMul:
+ mOut << "component-wise multiply";
+ break;
+ case EOpDiv:
+ mOut << "divide";
+ break;
+ case EOpIMod:
+ mOut << "modulo";
+ break;
+ case EOpBitShiftLeft:
+ mOut << "bit-wise shift left";
+ break;
+ case EOpBitShiftRight:
+ mOut << "bit-wise shift right";
+ break;
+ case EOpBitwiseAnd:
+ mOut << "bit-wise and";
+ break;
+ case EOpBitwiseXor:
+ mOut << "bit-wise xor";
+ break;
+ case EOpBitwiseOr:
+ mOut << "bit-wise or";
+ break;
+
+ case EOpEqual:
+ mOut << "Compare Equal";
+ break;
+ case EOpNotEqual:
+ mOut << "Compare Not Equal";
+ break;
+ case EOpLessThan:
+ mOut << "Compare Less Than";
+ break;
+ case EOpGreaterThan:
+ mOut << "Compare Greater Than";
+ break;
+ case EOpLessThanEqual:
+ mOut << "Compare Less Than or Equal";
+ break;
+ case EOpGreaterThanEqual:
+ mOut << "Compare Greater Than or Equal";
+ break;
+
+ case EOpVectorTimesScalar:
+ mOut << "vector-scale";
+ break;
+ case EOpVectorTimesMatrix:
+ mOut << "vector-times-matrix";
+ break;
+ case EOpMatrixTimesVector:
+ mOut << "matrix-times-vector";
+ break;
+ case EOpMatrixTimesScalar:
+ mOut << "matrix-scale";
+ break;
+ case EOpMatrixTimesMatrix:
+ mOut << "matrix-multiply";
+ break;
+
+ case EOpLogicalOr:
+ mOut << "logical-or";
+ break;
+ case EOpLogicalXor:
+ mOut << "logical-xor";
+ break;
+ case EOpLogicalAnd:
+ mOut << "logical-and";
+ break;
+ default:
+ mOut << "<unknown op>";
+ }
+
+ mOut << " (" << node->getType() << ")";
+
+ mOut << "\n";
+
+ // Special handling for direct indexes. Because constant
+ // unions are not aware they are struct indexes, treat them
+ // here where we have that contextual knowledge.
+ if (node->getOp() == EOpIndexDirectStruct || node->getOp() == EOpIndexDirectInterfaceBlock)
+ {
+ node->getLeft()->traverse(this);
+
+ TIntermConstantUnion *intermConstantUnion = node->getRight()->getAsConstantUnion();
+ ASSERT(intermConstantUnion);
+
+ OutputTreeText(mOut, intermConstantUnion, getCurrentIndentDepth() + 1);
+
+ // The following code finds the field name from the constant union
+ const TConstantUnion *constantUnion = intermConstantUnion->getConstantValue();
+ const TStructure *structure = node->getLeft()->getType().getStruct();
+ const TInterfaceBlock *interfaceBlock = node->getLeft()->getType().getInterfaceBlock();
+ ASSERT(structure || interfaceBlock);
+
+ const TFieldList &fields = structure ? structure->fields() : interfaceBlock->fields();
+
+ const TField *field = fields[constantUnion->getIConst()];
+
+ mOut << constantUnion->getIConst() << " (field '" << field->name() << "')";
+
+ mOut << "\n";
+
+ return false;
+ }
+
+ return true;
+}
+
+bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ const TOperator op = node->getOp();
+
+ switch (op)
+ {
+ // Give verbose names for ops that have special syntax and some built-in functions that are
+ // easy to confuse with others, but mostly use GLSL names for functions.
+ case EOpNegative:
+ mOut << "Negate value";
+ break;
+ case EOpPositive:
+ mOut << "Positive sign";
+ break;
+ case EOpLogicalNot:
+ mOut << "negation";
+ break;
+ case EOpBitwiseNot:
+ mOut << "bit-wise not";
+ break;
+
+ case EOpPostIncrement:
+ mOut << "Post-Increment";
+ break;
+ case EOpPostDecrement:
+ mOut << "Post-Decrement";
+ break;
+ case EOpPreIncrement:
+ mOut << "Pre-Increment";
+ break;
+ case EOpPreDecrement:
+ mOut << "Pre-Decrement";
+ break;
+
+ case EOpArrayLength:
+ mOut << "Array length";
+ break;
+
+ case EOpNotComponentWise:
+ mOut << "component-wise not";
+ break;
+
+ default:
+ if (BuiltInGroup::IsBuiltIn(op))
+ {
+ OutputFunction(mOut, "Call a built-in function", node->getFunction());
+ }
+ else
+ {
+ mOut << GetOperatorString(node->getOp());
+ }
+ break;
+ }
+
+ mOut << " (" << node->getType() << ")";
+
+ mOut << "\n";
+
+ return true;
+}
+
+bool TOutputTraverser::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Function Definition:\n";
+ return true;
+}
+
+bool TOutputTraverser::visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ if (node->isPrecise())
+ {
+ mOut << "Precise Declaration:\n";
+ }
+ else
+ {
+ mOut << "Invariant Declaration:\n";
+ }
+ return true;
+}
+
+void TOutputTraverser::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ OutputFunction(mOut, "Function Prototype", node->getFunction());
+ mOut << " (" << node->getType() << ")";
+ mOut << "\n";
+ size_t paramCount = node->getFunction()->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ const TVariable *param = node->getFunction()->getParam(i);
+ OutputTreeText(mOut, node, getCurrentIndentDepth() + 1);
+ mOut << "parameter: " << param->name() << " (" << param->getType() << ")\n";
+ }
+}
+
+bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ const TOperator op = node->getOp();
+
+ if (op == EOpNull)
+ {
+ mOut.prefix(SH_ERROR);
+ mOut << "node is still EOpNull!\n";
+ return true;
+ }
+
+ // Give verbose names for some built-in functions that are easy to confuse with others, but
+ // mostly use GLSL names for functions.
+ switch (op)
+ {
+ case EOpCallFunctionInAST:
+ OutputFunction(mOut, "Call a user-defined function", node->getFunction());
+ break;
+ case EOpCallInternalRawFunction:
+ OutputFunction(mOut, "Call an internal function with raw implementation",
+ node->getFunction());
+ break;
+
+ case EOpConstruct:
+ // The type of the constructor will be printed below.
+ mOut << "Construct";
+ break;
+
+ case EOpEqualComponentWise:
+ mOut << "component-wise equal";
+ break;
+ case EOpNotEqualComponentWise:
+ mOut << "component-wise not equal";
+ break;
+ case EOpLessThanComponentWise:
+ mOut << "component-wise less than";
+ break;
+ case EOpGreaterThanComponentWise:
+ mOut << "component-wise greater than";
+ break;
+ case EOpLessThanEqualComponentWise:
+ mOut << "component-wise less than or equal";
+ break;
+ case EOpGreaterThanEqualComponentWise:
+ mOut << "component-wise greater than or equal";
+ break;
+
+ case EOpDot:
+ mOut << "dot product";
+ break;
+ case EOpCross:
+ mOut << "cross product";
+ break;
+ case EOpMatrixCompMult:
+ mOut << "component-wise multiply";
+ break;
+
+ default:
+ if (BuiltInGroup::IsBuiltIn(op))
+ {
+ OutputFunction(mOut, "Call a built-in function", node->getFunction());
+ }
+ else
+ {
+ mOut << GetOperatorString(node->getOp());
+ }
+ break;
+ }
+
+ mOut << " (" << node->getType() << ")";
+
+ mOut << "\n";
+
+ return true;
+}
+
+bool TOutputTraverser::visitBlock(Visit visit, TIntermBlock *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Code block\n";
+
+ return true;
+}
+
+bool TOutputTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Declaration\n";
+
+ return true;
+}
+
+bool TOutputTraverser::visitTernary(Visit visit, TIntermTernary *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ mOut << "Ternary selection";
+ mOut << " (" << node->getType() << ")\n";
+
+ ++mIndentDepth;
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Condition\n";
+ node->getCondition()->traverse(this);
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ if (node->getTrueExpression())
+ {
+ mOut << "true case\n";
+ node->getTrueExpression()->traverse(this);
+ }
+ if (node->getFalseExpression())
+ {
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "false case\n";
+ node->getFalseExpression()->traverse(this);
+ }
+
+ --mIndentDepth;
+
+ return false;
+}
+
+bool TOutputTraverser::visitIfElse(Visit visit, TIntermIfElse *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ mOut << "If test\n";
+
+ ++mIndentDepth;
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Condition\n";
+ node->getCondition()->traverse(this);
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ if (node->getTrueBlock())
+ {
+ mOut << "true case\n";
+ node->getTrueBlock()->traverse(this);
+ }
+ else
+ {
+ mOut << "true case is null\n";
+ }
+
+ if (node->getFalseBlock())
+ {
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "false case\n";
+ node->getFalseBlock()->traverse(this);
+ }
+
+ --mIndentDepth;
+
+ return false;
+}
+
+bool TOutputTraverser::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ mOut << "Switch\n";
+
+ return true;
+}
+
+bool TOutputTraverser::visitCase(Visit visit, TIntermCase *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ if (node->getCondition() == nullptr)
+ {
+ mOut << "Default\n";
+ }
+ else
+ {
+ mOut << "Case\n";
+ }
+
+ return true;
+}
+
+void TOutputTraverser::visitConstantUnion(TIntermConstantUnion *node)
+{
+ size_t size = node->getType().getObjectSize();
+
+ for (size_t i = 0; i < size; i++)
+ {
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ switch (node->getConstantValue()[i].getType())
+ {
+ case EbtBool:
+ if (node->getConstantValue()[i].getBConst())
+ mOut << "true";
+ else
+ mOut << "false";
+
+ mOut << " ("
+ << "const bool"
+ << ")";
+ mOut << "\n";
+ break;
+ case EbtFloat:
+ mOut << node->getConstantValue()[i].getFConst();
+ mOut << " (const float)\n";
+ break;
+ case EbtInt:
+ mOut << node->getConstantValue()[i].getIConst();
+ mOut << " (const int)\n";
+ break;
+ case EbtUInt:
+ mOut << node->getConstantValue()[i].getUConst();
+ mOut << " (const uint)\n";
+ break;
+ case EbtYuvCscStandardEXT:
+ mOut << getYuvCscStandardEXTString(
+ node->getConstantValue()[i].getYuvCscStandardEXTConst());
+ mOut << " (const yuvCscStandardEXT)\n";
+ break;
+ default:
+ mOut.prefix(SH_ERROR);
+ mOut << "Unknown constant\n";
+ break;
+ }
+ }
+}
+
+bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ mOut << "Loop with condition ";
+ if (node->getType() == ELoopDoWhile)
+ mOut << "not ";
+ mOut << "tested first\n";
+
+ ++mIndentDepth;
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ if (node->getCondition())
+ {
+ mOut << "Loop Condition\n";
+ node->getCondition()->traverse(this);
+ }
+ else
+ {
+ mOut << "No loop condition\n";
+ }
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ if (node->getBody())
+ {
+ mOut << "Loop Body\n";
+ node->getBody()->traverse(this);
+ }
+ else
+ {
+ mOut << "No loop body\n";
+ }
+
+ if (node->getExpression())
+ {
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Loop Terminal Expression\n";
+ node->getExpression()->traverse(this);
+ }
+
+ --mIndentDepth;
+
+ return false;
+}
+
+bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ switch (node->getFlowOp())
+ {
+ case EOpKill:
+ mOut << "Branch: Kill";
+ break;
+ case EOpBreak:
+ mOut << "Branch: Break";
+ break;
+ case EOpContinue:
+ mOut << "Branch: Continue";
+ break;
+ case EOpReturn:
+ mOut << "Branch: Return";
+ break;
+ default:
+ mOut << "Branch: Unknown Branch";
+ break;
+ }
+
+ if (node->getExpression())
+ {
+ mOut << " with expression\n";
+ ++mIndentDepth;
+ node->getExpression()->traverse(this);
+ --mIndentDepth;
+ }
+ else
+ {
+ mOut << "\n";
+ }
+
+ return false;
+}
+
+} // anonymous namespace
+
+void OutputTree(TIntermNode *root, TInfoSinkBase &out)
+{
+ TOutputTraverser it(out);
+ ASSERT(root);
+ root->traverse(&it);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputTree.h b/gfx/angle/checkout/src/compiler/translator/OutputTree.h
new file mode 100644
index 0000000000..29bca65642
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputTree.h
@@ -0,0 +1,22 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Output the AST intermediate representation of the GLSL code.
+
+#ifndef COMPILER_TRANSLATOR_OUTPUTTREE_H_
+#define COMPILER_TRANSLATOR_OUTPUTTREE_H_
+
+namespace sh
+{
+
+class TIntermNode;
+class TInfoSinkBase;
+
+// Output the AST along with metadata.
+void OutputTree(TIntermNode *root, TInfoSinkBase &out);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OUTPUTTREE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ParseContext.cpp b/gfx/angle/checkout/src/compiler/translator/ParseContext.cpp
new file mode 100644
index 0000000000..4312c2c966
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ParseContext.cpp
@@ -0,0 +1,7538 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/ParseContext.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "compiler/preprocessor/SourceLocation.h"
+#include "compiler/translator/Declarator.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/ValidateGlobalInitializer.h"
+#include "compiler/translator/ValidateSwitch.h"
+#include "compiler/translator/glslang.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+///////////////////////////////////////////////////////////////////////
+//
+// Sub- vector and matrix fields
+//
+////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+
+const int kWebGLMaxStructNesting = 4;
+
+bool ContainsSampler(const TStructure *structType);
+
+bool ContainsSampler(const TType &type)
+{
+ if (IsSampler(type.getBasicType()))
+ {
+ return true;
+ }
+ if (type.getBasicType() == EbtStruct)
+ {
+ return ContainsSampler(type.getStruct());
+ }
+
+ return false;
+}
+
+bool ContainsSampler(const TStructure *structType)
+{
+ for (const auto &field : structType->fields())
+ {
+ if (ContainsSampler(*field->type()))
+ return true;
+ }
+ return false;
+}
+
+// Get a token from an image argument to use as an error message token.
+const char *GetImageArgumentToken(TIntermTyped *imageNode)
+{
+ ASSERT(IsImage(imageNode->getBasicType()));
+ while (imageNode->getAsBinaryNode() &&
+ (imageNode->getAsBinaryNode()->getOp() == EOpIndexIndirect ||
+ imageNode->getAsBinaryNode()->getOp() == EOpIndexDirect))
+ {
+ imageNode = imageNode->getAsBinaryNode()->getLeft();
+ }
+ TIntermSymbol *imageSymbol = imageNode->getAsSymbolNode();
+ if (imageSymbol)
+ {
+ return imageSymbol->getName().data();
+ }
+ return "image";
+}
+
+bool CanSetDefaultPrecisionOnType(const TPublicType &type)
+{
+ if (!SupportsPrecision(type.getBasicType()))
+ {
+ return false;
+ }
+ if (type.getBasicType() == EbtUInt)
+ {
+ // ESSL 3.00.4 section 4.5.4
+ return false;
+ }
+ if (type.isAggregate())
+ {
+ // Not allowed to set for aggregate types
+ return false;
+ }
+ return true;
+}
+
+// Map input primitive types to input array sizes in a geometry shader.
+GLuint GetGeometryShaderInputArraySize(TLayoutPrimitiveType primitiveType)
+{
+ switch (primitiveType)
+ {
+ case EptPoints:
+ return 1u;
+ case EptLines:
+ return 2u;
+ case EptTriangles:
+ return 3u;
+ case EptLinesAdjacency:
+ return 4u;
+ case EptTrianglesAdjacency:
+ return 6u;
+ default:
+ UNREACHABLE();
+ return 0u;
+ }
+}
+
+bool IsBufferOrSharedVariable(TIntermTyped *var)
+{
+ if (var->isInterfaceBlock() || var->getQualifier() == EvqBuffer ||
+ var->getQualifier() == EvqShared)
+ {
+ return true;
+ }
+ return false;
+}
+
+TIntermTyped *FindLValueBase(TIntermTyped *node)
+{
+ do
+ {
+ const TIntermBinary *binary = node->getAsBinaryNode();
+ if (binary == nullptr)
+ {
+ return node;
+ }
+
+ TOperator op = binary->getOp();
+ if (op != EOpIndexDirect && op != EOpIndexIndirect)
+ {
+ return static_cast<TIntermTyped *>(nullptr);
+ }
+
+ node = binary->getLeft();
+ } while (true);
+}
+
+void AddAdvancedBlendEquation(gl::BlendEquationType eq, TLayoutQualifier *qualifier)
+{
+ qualifier->advancedBlendEquations.set(static_cast<uint32_t>(eq));
+}
+
+constexpr bool IsValidWithPixelLocalStorage(TLayoutImageInternalFormat internalFormat)
+{
+ switch (internalFormat)
+ {
+ case EiifRGBA8:
+ case EiifRGBA8I:
+ case EiifRGBA8UI:
+ case EiifR32F:
+ case EiifR32UI:
+ return true;
+ default:
+ return false;
+ }
+}
+} // namespace
+
+// This tracks each binding point's current default offset for inheritance of subsequent
+// variables using the same binding, and keeps offsets unique and non overlapping.
+// See GLSL ES 3.1, section 4.4.6.
+class TParseContext::AtomicCounterBindingState
+{
+ public:
+ AtomicCounterBindingState() : mDefaultOffset(0) {}
+ // Inserts a new span and returns -1 if overlapping, else returns the starting offset of
+ // newly inserted span.
+ int insertSpan(int start, size_t length)
+ {
+ gl::RangeI newSpan(start, start + static_cast<int>(length));
+ for (const auto &span : mSpans)
+ {
+ if (newSpan.intersects(span))
+ {
+ return -1;
+ }
+ }
+ mSpans.push_back(newSpan);
+ mDefaultOffset = newSpan.high();
+ return start;
+ }
+ // Inserts a new span starting from the default offset.
+ int appendSpan(size_t length) { return insertSpan(mDefaultOffset, length); }
+ void setDefaultOffset(int offset) { mDefaultOffset = offset; }
+
+ private:
+ int mDefaultOffset;
+ std::vector<gl::RangeI> mSpans;
+};
+
+TParseContext::TParseContext(TSymbolTable &symt,
+ TExtensionBehavior &ext,
+ sh::GLenum type,
+ ShShaderSpec spec,
+ const ShCompileOptions &options,
+ bool checksPrecErrors,
+ TDiagnostics *diagnostics,
+ const ShBuiltInResources &resources,
+ ShShaderOutput outputType)
+ : symbolTable(symt),
+ mDeferredNonEmptyDeclarationErrorCheck(false),
+ mShaderType(type),
+ mShaderSpec(spec),
+ mCompileOptions(options),
+ mShaderVersion(100),
+ mTreeRoot(nullptr),
+ mLoopNestingLevel(0),
+ mStructNestingLevel(0),
+ mSwitchNestingLevel(0),
+ mCurrentFunctionType(nullptr),
+ mFunctionReturnsValue(false),
+ mChecksPrecisionErrors(checksPrecErrors),
+ mFragmentPrecisionHighOnESSL1(false),
+ mEarlyFragmentTestsSpecified(false),
+ mHasDiscard(false),
+ mSampleQualifierSpecified(false),
+ mDefaultUniformMatrixPacking(EmpColumnMajor),
+ mDefaultUniformBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
+ mDefaultBufferMatrixPacking(EmpColumnMajor),
+ mDefaultBufferBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
+ mDiagnostics(diagnostics),
+ mDirectiveHandler(ext, *mDiagnostics, mShaderVersion, mShaderType),
+ mPreprocessor(mDiagnostics, &mDirectiveHandler, angle::pp::PreprocessorSettings(spec)),
+ mScanner(nullptr),
+ mMinProgramTexelOffset(resources.MinProgramTexelOffset),
+ mMaxProgramTexelOffset(resources.MaxProgramTexelOffset),
+ mMinProgramTextureGatherOffset(resources.MinProgramTextureGatherOffset),
+ mMaxProgramTextureGatherOffset(resources.MaxProgramTextureGatherOffset),
+ mComputeShaderLocalSizeDeclared(false),
+ mComputeShaderLocalSize(-1),
+ mNumViews(-1),
+ mMaxNumViews(resources.MaxViewsOVR),
+ mMaxImageUnits(resources.MaxImageUnits),
+ mMaxCombinedTextureImageUnits(resources.MaxCombinedTextureImageUnits),
+ mMaxUniformLocations(resources.MaxUniformLocations),
+ mMaxUniformBufferBindings(resources.MaxUniformBufferBindings),
+ mMaxVertexAttribs(resources.MaxVertexAttribs),
+ mMaxAtomicCounterBindings(resources.MaxAtomicCounterBindings),
+ mMaxShaderStorageBufferBindings(resources.MaxShaderStorageBufferBindings),
+ mDeclaringFunction(false),
+ mGeometryShaderInputPrimitiveType(EptUndefined),
+ mGeometryShaderOutputPrimitiveType(EptUndefined),
+ mGeometryShaderInvocations(0),
+ mGeometryShaderMaxVertices(-1),
+ mMaxGeometryShaderInvocations(resources.MaxGeometryShaderInvocations),
+ mMaxGeometryShaderMaxVertices(resources.MaxGeometryOutputVertices),
+ mGeometryInputArraySize(0),
+ mMaxPatchVertices(resources.MaxPatchVertices),
+ mTessControlShaderOutputVertices(0),
+ mTessEvaluationShaderInputPrimitiveType(EtetUndefined),
+ mTessEvaluationShaderInputVertexSpacingType(EtetUndefined),
+ mTessEvaluationShaderInputOrderingType(EtetUndefined),
+ mTessEvaluationShaderInputPointType(EtetUndefined),
+ mHasAnyPreciseType(false),
+ mAdvancedBlendEquations(0),
+ mFunctionBodyNewScope(false),
+ mOutputType(outputType)
+{}
+
+TParseContext::~TParseContext() {}
+
+bool TParseContext::anyMultiviewExtensionAvailable()
+{
+ return isExtensionEnabled(TExtension::OVR_multiview) ||
+ isExtensionEnabled(TExtension::OVR_multiview2);
+}
+
+bool TParseContext::parseVectorFields(const TSourceLoc &line,
+ const ImmutableString &compString,
+ int vecSize,
+ TVector<int> *fieldOffsets)
+{
+ ASSERT(fieldOffsets);
+ size_t fieldCount = compString.length();
+ if (fieldCount > 4u)
+ {
+ error(line, "illegal vector field selection", compString);
+ return false;
+ }
+ fieldOffsets->resize(fieldCount);
+
+ enum
+ {
+ exyzw,
+ ergba,
+ estpq
+ } fieldSet[4];
+
+ for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
+ {
+ switch (compString[i])
+ {
+ case 'x':
+ (*fieldOffsets)[i] = 0;
+ fieldSet[i] = exyzw;
+ break;
+ case 'r':
+ (*fieldOffsets)[i] = 0;
+ fieldSet[i] = ergba;
+ break;
+ case 's':
+ (*fieldOffsets)[i] = 0;
+ fieldSet[i] = estpq;
+ break;
+ case 'y':
+ (*fieldOffsets)[i] = 1;
+ fieldSet[i] = exyzw;
+ break;
+ case 'g':
+ (*fieldOffsets)[i] = 1;
+ fieldSet[i] = ergba;
+ break;
+ case 't':
+ (*fieldOffsets)[i] = 1;
+ fieldSet[i] = estpq;
+ break;
+ case 'z':
+ (*fieldOffsets)[i] = 2;
+ fieldSet[i] = exyzw;
+ break;
+ case 'b':
+ (*fieldOffsets)[i] = 2;
+ fieldSet[i] = ergba;
+ break;
+ case 'p':
+ (*fieldOffsets)[i] = 2;
+ fieldSet[i] = estpq;
+ break;
+
+ case 'w':
+ (*fieldOffsets)[i] = 3;
+ fieldSet[i] = exyzw;
+ break;
+ case 'a':
+ (*fieldOffsets)[i] = 3;
+ fieldSet[i] = ergba;
+ break;
+ case 'q':
+ (*fieldOffsets)[i] = 3;
+ fieldSet[i] = estpq;
+ break;
+ default:
+ error(line, "illegal vector field selection", compString);
+ return false;
+ }
+ }
+
+ for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
+ {
+ if ((*fieldOffsets)[i] >= vecSize)
+ {
+ error(line, "vector field selection out of range", compString);
+ return false;
+ }
+
+ if (i > 0)
+ {
+ if (fieldSet[i] != fieldSet[i - 1])
+ {
+ error(line, "illegal - vector component fields not from the same set", compString);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// Errors
+//
+////////////////////////////////////////////////////////////////////////
+
+//
+// Used by flex/bison to output all syntax and parsing errors.
+//
+void TParseContext::error(const TSourceLoc &loc, const char *reason, const char *token)
+{
+ mDiagnostics->error(loc, reason, token);
+}
+
+void TParseContext::error(const TSourceLoc &loc, const char *reason, const ImmutableString &token)
+{
+ mDiagnostics->error(loc, reason, token.data());
+}
+
+void TParseContext::warning(const TSourceLoc &loc, const char *reason, const char *token)
+{
+ mDiagnostics->warning(loc, reason, token);
+}
+
+void TParseContext::errorIfPLSDeclared(const TSourceLoc &loc, PLSIllegalOperations op)
+{
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ return;
+ }
+ if (mPLSBindings.empty())
+ {
+ // No pixel local storage uniforms have been declared yet. Remember this potential error in
+ // case PLS gets declared later.
+ mPLSPotentialErrors.emplace_back(loc, op);
+ return;
+ }
+ switch (op)
+ {
+ case PLSIllegalOperations::Discard:
+ error(loc, "illegal discard when pixel local storage is declared", "discard");
+ break;
+ case PLSIllegalOperations::ReturnFromMain:
+ error(loc, "illegal return from main when pixel local storage is declared", "return");
+ break;
+ case PLSIllegalOperations::AssignFragDepth:
+ error(loc, "value not assignable when pixel local storage is declared", "gl_FragDepth");
+ break;
+ case PLSIllegalOperations::AssignSampleMask:
+ error(loc, "value not assignable when pixel local storage is declared",
+ "gl_SampleMask");
+ break;
+ }
+}
+
+void TParseContext::outOfRangeError(bool isError,
+ const TSourceLoc &loc,
+ const char *reason,
+ const char *token)
+{
+ if (isError)
+ {
+ error(loc, reason, token);
+ }
+ else
+ {
+ warning(loc, reason, token);
+ }
+}
+
+void TParseContext::setTreeRoot(TIntermBlock *treeRoot)
+{
+ mTreeRoot = treeRoot;
+ mTreeRoot->setIsTreeRoot();
+}
+
+//
+// Same error message for all places assignments don't work.
+//
+void TParseContext::assignError(const TSourceLoc &line,
+ const char *op,
+ const TType &left,
+ const TType &right)
+{
+ TInfoSinkBase reasonStream;
+ reasonStream << "cannot convert from '" << right << "' to '" << left << "'";
+ error(line, reasonStream.c_str(), op);
+}
+
+//
+// Same error message for all places unary operations don't work.
+//
+void TParseContext::unaryOpError(const TSourceLoc &line, const char *op, const TType &operand)
+{
+ TInfoSinkBase reasonStream;
+ reasonStream << "wrong operand type - no operation '" << op
+ << "' exists that takes an operand of type " << operand
+ << " (or there is no acceptable conversion)";
+ error(line, reasonStream.c_str(), op);
+}
+
+//
+// Same error message for all binary operations don't work.
+//
+void TParseContext::binaryOpError(const TSourceLoc &line,
+ const char *op,
+ const TType &left,
+ const TType &right)
+{
+ TInfoSinkBase reasonStream;
+ reasonStream << "wrong operand types - no operation '" << op
+ << "' exists that takes a left-hand operand of type '" << left
+ << "' and a right operand of type '" << right
+ << "' (or there is no acceptable conversion)";
+ error(line, reasonStream.c_str(), op);
+}
+
+void TParseContext::checkPrecisionSpecified(const TSourceLoc &line,
+ TPrecision precision,
+ TBasicType type)
+{
+ if (!mChecksPrecisionErrors)
+ return;
+
+ if (precision != EbpUndefined && !SupportsPrecision(type))
+ {
+ error(line, "illegal type for precision qualifier", getBasicString(type));
+ }
+
+ if (precision == EbpUndefined)
+ {
+ switch (type)
+ {
+ case EbtFloat:
+ error(line, "No precision specified for (float)", "");
+ return;
+ case EbtInt:
+ case EbtUInt:
+ UNREACHABLE(); // there's always a predeclared qualifier
+ error(line, "No precision specified (int)", "");
+ return;
+ default:
+ if (IsOpaqueType(type))
+ {
+ error(line, "No precision specified", getBasicString(type));
+ return;
+ }
+ }
+ }
+}
+
+void TParseContext::markStaticReadIfSymbol(TIntermNode *node)
+{
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ markStaticReadIfSymbol(swizzleNode->getOperand());
+ return;
+ }
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ markStaticReadIfSymbol(binaryNode->getLeft());
+ return;
+ default:
+ return;
+ }
+ }
+ TIntermSymbol *symbolNode = node->getAsSymbolNode();
+ if (symbolNode)
+ {
+ symbolTable.markStaticRead(symbolNode->variable());
+ }
+}
+
+// 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.
+bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node)
+{
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ bool ok = checkCanBeLValue(line, op, swizzleNode->getOperand());
+ if (ok && swizzleNode->hasDuplicateOffsets())
+ {
+ error(line, " l-value of swizzle cannot have duplicate components", op);
+ return false;
+ }
+ return ok;
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ if (node->getMemoryQualifier().readonly)
+ {
+ error(line, "can't modify a readonly variable", op);
+ return false;
+ }
+ return checkCanBeLValue(line, op, binaryNode->getLeft());
+ default:
+ break;
+ }
+ error(line, " l-value required", op);
+ return false;
+ }
+
+ std::string message;
+ switch (node->getQualifier())
+ {
+ case EvqConst:
+ message = "can't modify a const";
+ break;
+ case EvqParamConst:
+ message = "can't modify a const";
+ break;
+ case EvqAttribute:
+ message = "can't modify an attribute";
+ break;
+ case EvqFragmentIn:
+ case EvqVertexIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ case EvqFlatIn:
+ case EvqNoPerspectiveIn:
+ case EvqSmoothIn:
+ case EvqCentroidIn:
+ case EvqSampleIn:
+ message = "can't modify an input";
+ break;
+ case EvqUniform:
+ message = "can't modify a uniform";
+ break;
+ case EvqVaryingIn:
+ message = "can't modify a varying";
+ break;
+ case EvqFragCoord:
+ message = "can't modify gl_FragCoord";
+ break;
+ case EvqFrontFacing:
+ message = "can't modify gl_FrontFacing";
+ break;
+ case EvqHelperInvocation:
+ message = "can't modify gl_HelperInvocation";
+ break;
+ case EvqPointCoord:
+ message = "can't modify gl_PointCoord";
+ break;
+ case EvqNumWorkGroups:
+ message = "can't modify gl_NumWorkGroups";
+ break;
+ case EvqWorkGroupSize:
+ message = "can't modify gl_WorkGroupSize";
+ break;
+ case EvqWorkGroupID:
+ message = "can't modify gl_WorkGroupID";
+ break;
+ case EvqLocalInvocationID:
+ message = "can't modify gl_LocalInvocationID";
+ break;
+ case EvqGlobalInvocationID:
+ message = "can't modify gl_GlobalInvocationID";
+ break;
+ case EvqLocalInvocationIndex:
+ message = "can't modify gl_LocalInvocationIndex";
+ break;
+ case EvqViewIDOVR:
+ message = "can't modify gl_ViewID_OVR";
+ break;
+ case EvqComputeIn:
+ message = "can't modify work group size variable";
+ break;
+ case EvqPerVertexIn:
+ message = "can't modify any member in gl_in";
+ break;
+ case EvqPrimitiveIDIn:
+ message = "can't modify gl_PrimitiveIDIn";
+ break;
+ case EvqInvocationID:
+ message = "can't modify gl_InvocationID";
+ break;
+ case EvqPrimitiveID:
+ if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ message = "can't modify gl_PrimitiveID in a fragment shader";
+ }
+ break;
+ case EvqLayerIn:
+ message = "can't modify gl_Layer in a fragment shader";
+ break;
+ case EvqSampleID:
+ message = "can't modify gl_SampleID";
+ break;
+ case EvqSampleMaskIn:
+ message = "can't modify gl_SampleMaskIn";
+ break;
+ case EvqSamplePosition:
+ message = "can't modify gl_SamplePosition";
+ break;
+ case EvqClipDistance:
+ if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ message = "can't modify gl_ClipDistance in a fragment shader";
+ }
+ break;
+ case EvqCullDistance:
+ if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ message = "can't modify gl_CullDistance in a fragment shader";
+ }
+ break;
+ case EvqFragDepth:
+ errorIfPLSDeclared(line, PLSIllegalOperations::AssignFragDepth);
+ break;
+ case EvqSampleMask:
+ errorIfPLSDeclared(line, PLSIllegalOperations::AssignSampleMask);
+ break;
+ default:
+ //
+ // Type that can't be written to?
+ //
+ if (node->getBasicType() == EbtVoid)
+ {
+ message = "can't modify void";
+ }
+ if (IsOpaqueType(node->getBasicType()))
+ {
+ message = "can't modify a variable with type ";
+ message += getBasicString(node->getBasicType());
+ }
+ else if (node->getMemoryQualifier().readonly)
+ {
+ message = "can't modify a readonly variable";
+ }
+ }
+
+ ASSERT(binaryNode == nullptr && swizzleNode == nullptr);
+ TIntermSymbol *symNode = node->getAsSymbolNode();
+ if (message.empty() && symNode != nullptr)
+ {
+ symbolTable.markStaticWrite(symNode->variable());
+ return true;
+ }
+
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
+ reasonStream << "l-value required";
+ if (!message.empty())
+ {
+ if (symNode)
+ {
+ // Symbol inside an expression can't be nameless.
+ ASSERT(symNode->variable().symbolType() != SymbolType::Empty);
+ const ImmutableString &symbol = symNode->getName();
+ reasonStream << " (" << message << " \"" << symbol << "\")";
+ }
+ else
+ {
+ reasonStream << " (" << message << ")";
+ }
+ }
+ std::string reason = reasonStream.str();
+ error(line, reason.c_str(), op);
+
+ return false;
+}
+
+// Both test, and if necessary spit out an error, to see if the node is really
+// a constant.
+void TParseContext::checkIsConst(TIntermTyped *node)
+{
+ if (node->getQualifier() != EvqConst)
+ {
+ error(node->getLine(), "constant expression required", "");
+ }
+}
+
+// Both test, and if necessary spit out an error, to see if the node is really
+// an integer.
+void TParseContext::checkIsScalarInteger(TIntermTyped *node, const char *token)
+{
+ if (!node->isScalarInt())
+ {
+ error(node->getLine(), "integer expression required", token);
+ }
+}
+
+// Both test, and if necessary spit out an error, to see if we are currently
+// globally scoped.
+bool TParseContext::checkIsAtGlobalLevel(const TSourceLoc &line, const char *token)
+{
+ if (!symbolTable.atGlobalLevel())
+ {
+ error(line, "only allowed at global scope", token);
+ return false;
+ }
+ return true;
+}
+
+// ESSL 3.00.5 sections 3.8 and 3.9.
+// If it starts "gl_" or contains two consecutive underscores, it's reserved.
+// Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a webgl shader.
+bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const ImmutableString &identifier)
+{
+ static const char *reservedErrMsg = "reserved built-in name";
+ if (gl::IsBuiltInName(identifier.data()))
+ {
+ error(line, reservedErrMsg, "gl_");
+ return false;
+ }
+ if (sh::IsWebGLBasedSpec(mShaderSpec))
+ {
+ if (identifier.beginsWith("webgl_"))
+ {
+ error(line, reservedErrMsg, "webgl_");
+ return false;
+ }
+ if (identifier.beginsWith("_webgl_"))
+ {
+ error(line, reservedErrMsg, "_webgl_");
+ return false;
+ }
+ }
+ if (identifier.contains("__"))
+ {
+ if (sh::IsWebGLBasedSpec(mShaderSpec))
+ {
+ error(line,
+ "identifiers containing two consecutive underscores (__) are reserved as "
+ "possible future keywords",
+ identifier);
+ return false;
+ }
+ else
+ {
+ // Using double underscores is allowed, but may result in unintended behaviors, so a
+ // warning is issued.
+ // OpenGL ES Shader Language 3.2 specification:
+ // > 3.7. Keywords
+ // > ...
+ // > In addition, all identifiers containing two consecutive underscores (__) are
+ // > reserved for use by underlying software layers. Defining such a name in a shader
+ // > does not itself result in an error, but may result in unintended behaviors that
+ // > stem from having multiple definitions of the same name.
+ warning(line,
+ "all identifiers containing two consecutive underscores (__) are reserved - "
+ "unintented behaviors are possible",
+ identifier.data());
+ }
+ }
+ return true;
+}
+
+// Make sure the argument types are correct for constructing a specific type.
+bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
+ const TIntermSequence &arguments,
+ const TType &type)
+{
+ if (arguments.empty())
+ {
+ error(line, "constructor does not have any arguments", "constructor");
+ return false;
+ }
+
+ for (TIntermNode *arg : arguments)
+ {
+ markStaticReadIfSymbol(arg);
+ const TIntermTyped *argTyped = arg->getAsTyped();
+ ASSERT(argTyped != nullptr);
+ if (type.getBasicType() != EbtStruct && IsOpaqueType(argTyped->getBasicType()))
+ {
+ std::string reason("cannot convert a variable with type ");
+ reason += getBasicString(argTyped->getBasicType());
+ error(line, reason.c_str(), "constructor");
+ return false;
+ }
+ else if (argTyped->getMemoryQualifier().writeonly)
+ {
+ error(line, "cannot convert a variable with writeonly", "constructor");
+ return false;
+ }
+ if (argTyped->getBasicType() == EbtVoid)
+ {
+ error(line, "cannot convert a void", "constructor");
+ return false;
+ }
+ }
+
+ if (type.isArray())
+ {
+ // The size of an unsized constructor should already have been determined.
+ ASSERT(!type.isUnsizedArray());
+ if (static_cast<size_t>(type.getOutermostArraySize()) != arguments.size())
+ {
+ error(line, "array constructor needs one argument per array element", "constructor");
+ return false;
+ }
+ // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
+ // the array.
+ for (TIntermNode *const &argNode : arguments)
+ {
+ const TType &argType = argNode->getAsTyped()->getType();
+ if (mShaderVersion < 310 && argType.isArray())
+ {
+ error(line, "constructing from a non-dereferenced array", "constructor");
+ return false;
+ }
+ if (!argType.isElementTypeOf(type))
+ {
+ error(line, "Array constructor argument has an incorrect type", "constructor");
+ return false;
+ }
+ }
+ }
+ else if (type.getBasicType() == EbtStruct)
+ {
+ const TFieldList &fields = type.getStruct()->fields();
+ if (fields.size() != arguments.size())
+ {
+ error(line,
+ "Number of constructor parameters does not match the number of structure fields",
+ "constructor");
+ return false;
+ }
+
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ if (i >= arguments.size() ||
+ arguments[i]->getAsTyped()->getType() != *fields[i]->type())
+ {
+ error(line, "Structure constructor arguments do not match structure fields",
+ "constructor");
+ return false;
+ }
+ }
+ }
+ else
+ {
+ // We're constructing a scalar, vector, or matrix.
+
+ // Note: It's okay to have too many components available, but not okay to have unused
+ // arguments. 'full' will go to true when enough args have been seen. If we loop again,
+ // there is an extra argument, so 'overFull' will become true.
+
+ size_t size = 0;
+ bool full = false;
+ bool overFull = false;
+ bool matrixArg = false;
+ for (TIntermNode *arg : arguments)
+ {
+ const TIntermTyped *argTyped = arg->getAsTyped();
+ ASSERT(argTyped != nullptr);
+
+ if (argTyped->getBasicType() == EbtStruct)
+ {
+ error(line, "a struct cannot be used as a constructor argument for this type",
+ "constructor");
+ return false;
+ }
+ if (argTyped->getType().isArray())
+ {
+ error(line, "constructing from a non-dereferenced array", "constructor");
+ return false;
+ }
+ if (argTyped->getType().isMatrix())
+ {
+ matrixArg = true;
+ }
+
+ size += argTyped->getType().getObjectSize();
+ if (full)
+ {
+ overFull = true;
+ }
+ if (size >= type.getObjectSize())
+ {
+ full = true;
+ }
+ }
+
+ if (type.isMatrix() && matrixArg)
+ {
+ if (arguments.size() != 1)
+ {
+ error(line, "constructing matrix from matrix can only take one argument",
+ "constructor");
+ return false;
+ }
+ }
+ else
+ {
+ if (size != 1 && size < type.getObjectSize())
+ {
+ error(line, "not enough data provided for construction", "constructor");
+ return false;
+ }
+ if (overFull)
+ {
+ error(line, "too many arguments", "constructor");
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+// This function checks to see if a void variable has been declared and raise an error message for
+// such a case
+//
+// returns true in case of an error
+//
+bool TParseContext::checkIsNonVoid(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const TBasicType &type)
+{
+ if (type == EbtVoid)
+ {
+ error(line, "illegal use of type 'void'", identifier);
+ return false;
+ }
+
+ return true;
+}
+
+// This function checks to see if the node (for the expression) contains a scalar boolean expression
+// or not.
+bool TParseContext::checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type)
+{
+ if (type->getBasicType() != EbtBool || !type->isScalar())
+ {
+ error(line, "boolean expression expected", "");
+ return false;
+ }
+ return true;
+}
+
+// This function checks to see if the node (for the expression) contains a scalar boolean expression
+// or not.
+void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType)
+{
+ if (pType.getBasicType() != EbtBool || pType.isAggregate())
+ {
+ error(line, "boolean expression expected", "");
+ }
+}
+
+bool TParseContext::checkIsNotOpaqueType(const TSourceLoc &line,
+ const TTypeSpecifierNonArray &pType,
+ const char *reason)
+{
+ if (pType.type == EbtStruct)
+ {
+ if (ContainsSampler(pType.userDef))
+ {
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
+ reasonStream << reason << " (structure contains a sampler)";
+ std::string reasonStr = reasonStream.str();
+ error(line, reasonStr.c_str(), getBasicString(pType.type));
+ return false;
+ }
+ // only samplers need to be checked from structs, since other opaque types can't be struct
+ // members.
+ return true;
+ }
+ else if (IsOpaqueType(pType.type))
+ {
+ error(line, reason, getBasicString(pType.type));
+ return false;
+ }
+
+ return true;
+}
+
+void TParseContext::checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line,
+ const TPublicType &pType)
+{
+ if (pType.layoutQualifier.location != -1)
+ {
+ error(line, "location must only be specified for a single input or output variable",
+ "location");
+ }
+}
+
+void TParseContext::checkLocationIsNotSpecified(const TSourceLoc &location,
+ const TLayoutQualifier &layoutQualifier)
+{
+ if (layoutQualifier.location != -1)
+ {
+ const char *errorMsg = "invalid layout qualifier: only valid on program inputs and outputs";
+ if (mShaderVersion >= 310)
+ {
+ errorMsg =
+ "invalid layout qualifier: only valid on shader inputs, outputs, and uniforms";
+ }
+ error(location, errorMsg, "location");
+ }
+}
+
+void TParseContext::checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
+ const TLayoutBlockStorage &blockStorage,
+ const TQualifier &qualifier)
+{
+ if (blockStorage == EbsStd430 && qualifier != EvqBuffer)
+ {
+ error(location, "The std430 layout is supported only for shader storage blocks.", "std430");
+ }
+}
+
+void TParseContext::checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
+ TQualifier qualifier,
+ const TType &type)
+{
+ ASSERT(qualifier == EvqParamOut || qualifier == EvqParamInOut);
+ if (IsOpaqueType(type.getBasicType()))
+ {
+ error(line, "opaque types cannot be output parameters", type.getBasicString());
+ }
+}
+
+// Do size checking for an array type's size.
+unsigned int TParseContext::checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr)
+{
+ TIntermConstantUnion *constant = expr->getAsConstantUnion();
+
+ // ANGLE should be able to fold any EvqConst expressions resulting in an integer - but to be
+ // safe against corner cases we still check for constant folding. Some interpretations of the
+ // spec have allowed constant expressions with side effects - like array length() method on a
+ // non-constant array.
+ if (expr->getQualifier() != EvqConst || constant == nullptr || !constant->isScalarInt())
+ {
+ error(line, "array size must be a constant integer expression", "");
+ return 1u;
+ }
+
+ unsigned int size = 0u;
+
+ if (constant->getBasicType() == EbtUInt)
+ {
+ size = constant->getUConst(0);
+ }
+ else
+ {
+ int signedSize = constant->getIConst(0);
+
+ if (signedSize < 0)
+ {
+ error(line, "array size must be non-negative", "");
+ return 1u;
+ }
+
+ size = static_cast<unsigned int>(signedSize);
+ }
+
+ if (size == 0u)
+ {
+ error(line, "array size must be greater than zero", "");
+ return 1u;
+ }
+
+ if (IsOutputHLSL(getOutputType()))
+ {
+ // The size of arrays is restricted here to prevent issues further down the
+ // compiler/translator/driver stack. Shader Model 5 generation hardware is limited to
+ // 4096 registers so this should be reasonable even for aggressively optimizable code.
+ const unsigned int sizeLimit = 65536;
+
+ if (size > sizeLimit)
+ {
+ error(line, "array size too large", "");
+ return 1u;
+ }
+ }
+
+ return size;
+}
+
+// See if this qualifier can be an array.
+bool TParseContext::checkIsValidQualifierForArray(const TSourceLoc &line,
+ const TPublicType &elementQualifier)
+{
+ if ((elementQualifier.qualifier == EvqAttribute) ||
+ (elementQualifier.qualifier == EvqVertexIn) ||
+ (elementQualifier.qualifier == EvqConst && mShaderVersion < 300))
+ {
+ error(line, "cannot declare arrays of this qualifier",
+ TType(elementQualifier).getQualifierString());
+ return false;
+ }
+
+ return true;
+}
+
+// See if this element type can be formed into an array.
+bool TParseContext::checkArrayElementIsNotArray(const TSourceLoc &line,
+ const TPublicType &elementType)
+{
+ if (mShaderVersion < 310 && elementType.isArray())
+ {
+ TInfoSinkBase typeString;
+ typeString << TType(elementType);
+ error(line, "cannot declare arrays of arrays", typeString.c_str());
+ return false;
+ }
+ return true;
+}
+
+// Check for array-of-arrays being used as non-allowed shader inputs/outputs.
+bool TParseContext::checkArrayOfArraysInOut(const TSourceLoc &line,
+ const TPublicType &elementType,
+ const TType &arrayType)
+{
+ if (arrayType.isArrayOfArrays())
+ {
+ if (elementType.qualifier == EvqVertexOut)
+ {
+ error(line, "vertex shader output cannot be an array of arrays",
+ TType(elementType).getQualifierString());
+ return false;
+ }
+ if (elementType.qualifier == EvqFragmentIn)
+ {
+ error(line, "fragment shader input cannot be an array of arrays",
+ TType(elementType).getQualifierString());
+ return false;
+ }
+ if (elementType.qualifier == EvqFragmentOut || elementType.qualifier == EvqFragmentInOut)
+ {
+ error(line, "fragment shader output cannot be an array of arrays",
+ TType(elementType).getQualifierString());
+ return false;
+ }
+ }
+ return true;
+}
+
+// Check if this qualified element type can be formed into an array. This is only called when array
+// brackets are associated with an identifier in a declaration, like this:
+// float a[2];
+// Similar checks are done in addFullySpecifiedType for array declarations where the array brackets
+// are associated with the type, like this:
+// float[2] a;
+bool TParseContext::checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
+ const TPublicType &elementType)
+{
+ if (!checkArrayElementIsNotArray(indexLocation, elementType))
+ {
+ return false;
+ }
+ // In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere.
+ // In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section
+ // 4.3.4).
+ // Geometry shader requires each user-defined input be declared as arrays or inside input
+ // blocks declared as arrays (GL_EXT_geometry_shader section 11.1gs.4.3). For the purposes of
+ // interface matching, such variables and blocks are treated as though they were not declared
+ // as arrays (GL_EXT_geometry_shader section 7.4.1).
+ if (mShaderVersion >= 300 && elementType.getBasicType() == EbtStruct &&
+ sh::IsVarying(elementType.qualifier) &&
+ !IsGeometryShaderInput(mShaderType, elementType.qualifier) &&
+ !IsTessellationControlShaderInput(mShaderType, elementType.qualifier) &&
+ !IsTessellationEvaluationShaderInput(mShaderType, elementType.qualifier) &&
+ !IsTessellationControlShaderOutput(mShaderType, elementType.qualifier))
+ {
+ TInfoSinkBase typeString;
+ typeString << TType(elementType);
+ error(indexLocation, "cannot declare arrays of structs of this qualifier",
+ typeString.c_str());
+ return false;
+ }
+ return checkIsValidQualifierForArray(indexLocation, elementType);
+}
+
+// Enforce non-initializer type/qualifier rules.
+void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ TType *type)
+{
+ ASSERT(type != nullptr);
+ if (type->getQualifier() == EvqConst)
+ {
+ // Make the qualifier make sense.
+ type->setQualifier(EvqTemporary);
+
+ // Generate informative error messages for ESSL1.
+ // In ESSL3 arrays and structures containing arrays can be constant.
+ if (mShaderVersion < 300 && type->isStructureContainingArrays())
+ {
+ error(line,
+ "structures containing arrays may not be declared constant since they cannot be "
+ "initialized",
+ identifier);
+ }
+ else
+ {
+ error(line, "variables with qualifier 'const' must be initialized", identifier);
+ }
+ }
+
+ // Implicitly declared arrays are only allowed with tessellation or geometry shader inputs
+ if (type->isArray() &&
+ ((mShaderType != GL_TESS_CONTROL_SHADER && mShaderType != GL_TESS_EVALUATION_SHADER &&
+ mShaderType != GL_GEOMETRY_SHADER) ||
+ (mShaderType == GL_GEOMETRY_SHADER && type->getQualifier() == EvqGeometryOut)))
+ {
+ const TSpan<const unsigned int> &arraySizes = type->getArraySizes();
+ for (unsigned int size : arraySizes)
+ {
+ if (size == 0)
+ {
+ error(line,
+ "implicitly sized arrays only allowed for tessellation shaders "
+ "or geometry shader inputs",
+ identifier);
+ }
+ }
+ }
+}
+
+// Do some simple checks that are shared between all variable declarations,
+// and update the symbol table.
+//
+// Returns true if declaring the variable succeeded.
+//
+bool TParseContext::declareVariable(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const TType *type,
+ TVariable **variable)
+{
+ ASSERT((*variable) == nullptr);
+
+ SymbolType symbolType = SymbolType::UserDefined;
+ switch (type->getQualifier())
+ {
+ case EvqClipDistance:
+ case EvqCullDistance:
+ case EvqLastFragData:
+ symbolType = SymbolType::BuiltIn;
+ break;
+ default:
+ break;
+ }
+
+ (*variable) = new TVariable(&symbolTable, identifier, type, symbolType);
+
+ ASSERT(type->getLayoutQualifier().index == -1 ||
+ (isExtensionEnabled(TExtension::EXT_blend_func_extended) &&
+ mShaderType == GL_FRAGMENT_SHADER && mShaderVersion >= 300));
+ if (type->getQualifier() == EvqFragmentOut)
+ {
+ if (type->getLayoutQualifier().index != -1 && type->getLayoutQualifier().location == -1)
+ {
+ error(line,
+ "If index layout qualifier is specified for a fragment output, location must "
+ "also be specified.",
+ "index");
+ return false;
+ }
+ }
+ else
+ {
+ checkIndexIsNotSpecified(line, type->getLayoutQualifier().index);
+ }
+
+ if (!((identifier.beginsWith("gl_LastFragData") || type->getQualifier() == EvqFragmentInOut) &&
+ (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
+ isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent))))
+ {
+ checkNoncoherentIsNotSpecified(line, type->getLayoutQualifier().noncoherent);
+ }
+ else if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent) &&
+ !isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch))
+ {
+ checkNoncoherentIsSpecified(line, type->getLayoutQualifier().noncoherent);
+ }
+
+ checkBindingIsValid(line, *type);
+
+ bool needsReservedCheck = true;
+
+ // gl_LastFragData may be redeclared with a new precision qualifier
+ if (type->isArray() && identifier.beginsWith("gl_LastFragData"))
+ {
+ const TVariable *maxDrawBuffers = static_cast<const TVariable *>(
+ symbolTable.findBuiltIn(ImmutableString("gl_MaxDrawBuffers"), mShaderVersion));
+ if (type->isArrayOfArrays())
+ {
+ error(line, "redeclaration of gl_LastFragData as an array of arrays", identifier);
+ return false;
+ }
+ else if (static_cast<int>(type->getOutermostArraySize()) ==
+ maxDrawBuffers->getConstPointer()->getIConst())
+ {
+ if (const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
+ {
+ needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
+ }
+ }
+ else
+ {
+ error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers",
+ identifier);
+ return false;
+ }
+ }
+ else if (type->isArray() && identifier == "gl_ClipDistance")
+ {
+ // gl_ClipDistance can be redeclared with smaller size than gl_MaxClipDistances
+ const TVariable *maxClipDistances = static_cast<const TVariable *>(
+ symbolTable.findBuiltIn(ImmutableString("gl_MaxClipDistances"), mShaderVersion));
+ if (!maxClipDistances)
+ {
+ // Unsupported extension
+ needsReservedCheck = true;
+ }
+ else if (type->isArrayOfArrays())
+ {
+ error(line, "redeclaration of gl_ClipDistance as an array of arrays", identifier);
+ return false;
+ }
+ else if (static_cast<int>(type->getOutermostArraySize()) <=
+ maxClipDistances->getConstPointer()->getIConst())
+ {
+ const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion);
+ if (builtInSymbol)
+ {
+ needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
+ }
+ }
+ else
+ {
+ error(line, "redeclaration of gl_ClipDistance with size > gl_MaxClipDistances",
+ identifier);
+ return false;
+ }
+ }
+ else if (type->isArray() && identifier == "gl_CullDistance")
+ {
+ // gl_CullDistance can be redeclared with smaller size than gl_MaxCullDistances
+ const TVariable *maxCullDistances = static_cast<const TVariable *>(
+ symbolTable.findBuiltIn(ImmutableString("gl_MaxCullDistances"), mShaderVersion));
+ if (!maxCullDistances)
+ {
+ // Unsupported extension
+ needsReservedCheck = true;
+ }
+ else if (type->isArrayOfArrays())
+ {
+ error(line, "redeclaration of gl_CullDistance as an array of arrays", identifier);
+ return false;
+ }
+ else if (static_cast<int>(type->getOutermostArraySize()) <=
+ maxCullDistances->getConstPointer()->getIConst())
+ {
+ if (const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
+ {
+ needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
+ }
+ }
+ else
+ {
+ error(line, "redeclaration of gl_CullDistance with size > gl_MaxCullDistances",
+ identifier);
+ return false;
+ }
+ }
+
+ if (needsReservedCheck && !checkIsNotReserved(line, identifier))
+ return false;
+
+ if (!symbolTable.declare(*variable))
+ {
+ error(line, "redefinition", identifier);
+ return false;
+ }
+
+ if (!checkIsNonVoid(line, identifier, type->getBasicType()))
+ return false;
+
+ return true;
+}
+
+void TParseContext::checkIsParameterQualifierValid(
+ const TSourceLoc &line,
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ TType *type)
+{
+ // The only parameter qualifiers a parameter can have are in, out, inout or const.
+ TTypeQualifier typeQualifier =
+ typeQualifierBuilder.getParameterTypeQualifier(type->getBasicType(), mDiagnostics);
+
+ if (typeQualifier.qualifier == EvqParamOut || typeQualifier.qualifier == EvqParamInOut)
+ {
+ checkOutParameterIsNotOpaqueType(line, typeQualifier.qualifier, *type);
+ }
+
+ if (!IsImage(type->getBasicType()))
+ {
+ checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, line);
+ }
+ else
+ {
+ type->setMemoryQualifier(typeQualifier.memoryQualifier);
+ }
+
+ type->setQualifier(typeQualifier.qualifier);
+
+ if (typeQualifier.precision != EbpUndefined)
+ {
+ type->setPrecision(typeQualifier.precision);
+ }
+
+ if (typeQualifier.precise)
+ {
+ type->setPrecise(true);
+ }
+}
+
+template <size_t size>
+bool TParseContext::checkCanUseOneOfExtensions(const TSourceLoc &line,
+ const std::array<TExtension, size> &extensions)
+{
+ ASSERT(!extensions.empty());
+ const TExtensionBehavior &extBehavior = extensionBehavior();
+
+ bool canUseWithWarning = false;
+ bool canUseWithoutWarning = false;
+
+ const char *errorMsgString = "";
+ TExtension errorMsgExtension = TExtension::UNDEFINED;
+
+ for (TExtension extension : extensions)
+ {
+ auto extIter = extBehavior.find(extension);
+ if (canUseWithWarning)
+ {
+ // We already have an extension that we can use, but with a warning.
+ // See if we can use the alternative extension without a warning.
+ if (extIter == extBehavior.end())
+ {
+ continue;
+ }
+ if (extIter->second == EBhEnable || extIter->second == EBhRequire)
+ {
+ canUseWithoutWarning = true;
+ break;
+ }
+ continue;
+ }
+ if (extension == TExtension::UNDEFINED)
+ {
+ continue;
+ }
+ else if (extIter == extBehavior.end())
+ {
+ errorMsgString = "extension is not supported";
+ errorMsgExtension = extension;
+ }
+ else if (extIter->second == EBhUndefined || extIter->second == EBhDisable)
+ {
+ errorMsgString = "extension is disabled";
+ errorMsgExtension = extension;
+ }
+ else if (extIter->second == EBhWarn)
+ {
+ errorMsgExtension = extension;
+ canUseWithWarning = true;
+ }
+ else
+ {
+ ASSERT(extIter->second == EBhEnable || extIter->second == EBhRequire);
+ canUseWithoutWarning = true;
+ break;
+ }
+ }
+
+ if (canUseWithoutWarning)
+ {
+ return true;
+ }
+ if (canUseWithWarning)
+ {
+ warning(line, "extension is being used", GetExtensionNameString(errorMsgExtension));
+ return true;
+ }
+ error(line, errorMsgString, GetExtensionNameString(errorMsgExtension));
+ return false;
+}
+
+template bool TParseContext::checkCanUseOneOfExtensions(
+ const TSourceLoc &line,
+ const std::array<TExtension, 1> &extensions);
+template bool TParseContext::checkCanUseOneOfExtensions(
+ const TSourceLoc &line,
+ const std::array<TExtension, 2> &extensions);
+template bool TParseContext::checkCanUseOneOfExtensions(
+ const TSourceLoc &line,
+ const std::array<TExtension, 3> &extensions);
+
+bool TParseContext::checkCanUseExtension(const TSourceLoc &line, TExtension extension)
+{
+ ASSERT(extension != TExtension::UNDEFINED);
+ return checkCanUseOneOfExtensions(line, std::array<TExtension, 1u>{{extension}});
+}
+
+// ESSL 3.00.6 section 4.8 Empty Declarations: "The combinations of qualifiers that cause
+// compile-time or link-time errors are the same whether or not the declaration is empty".
+// This function implements all the checks that are done on qualifiers regardless of if the
+// declaration is empty.
+void TParseContext::declarationQualifierErrorCheck(const sh::TQualifier qualifier,
+ const sh::TLayoutQualifier &layoutQualifier,
+ const TSourceLoc &location)
+{
+ if (qualifier == EvqShared && !layoutQualifier.isEmpty())
+ {
+ error(location, "Shared memory declarations cannot have layout specified", "layout");
+ }
+
+ if (layoutQualifier.matrixPacking != EmpUnspecified)
+ {
+ error(location, "layout qualifier only valid for interface blocks",
+ getMatrixPackingString(layoutQualifier.matrixPacking));
+ return;
+ }
+
+ if (layoutQualifier.blockStorage != EbsUnspecified)
+ {
+ error(location, "layout qualifier only valid for interface blocks",
+ getBlockStorageString(layoutQualifier.blockStorage));
+ return;
+ }
+
+ if (qualifier == EvqFragmentOut)
+ {
+ if (layoutQualifier.location != -1 && layoutQualifier.yuv == true)
+ {
+ error(location, "invalid layout qualifier combination", "yuv");
+ return;
+ }
+ }
+ else
+ {
+ checkYuvIsNotSpecified(location, layoutQualifier.yuv);
+ }
+
+ if (qualifier != EvqFragmentIn)
+ {
+ checkEarlyFragmentTestsIsNotSpecified(location, layoutQualifier.earlyFragmentTests);
+ }
+
+ // If multiview extension is enabled, "in" qualifier is allowed in the vertex shader in previous
+ // parsing steps. So it needs to be checked here.
+ if (anyMultiviewExtensionAvailable() && mShaderVersion < 300 && qualifier == EvqVertexIn)
+ {
+ error(location, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
+ }
+
+ bool canHaveLocation = qualifier == EvqVertexIn || qualifier == EvqFragmentOut;
+ if (mShaderVersion >= 300 &&
+ (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
+ isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent)))
+ {
+ // In the case of EXT_shader_framebuffer_fetch or EXT_shader_framebuffer_fetch_non_coherent
+ // extension, the location of inout qualifier is used to set the input attachment index
+ canHaveLocation = canHaveLocation || qualifier == EvqFragmentInOut;
+ }
+ if (mShaderVersion >= 310)
+ {
+ canHaveLocation = canHaveLocation || qualifier == EvqUniform || IsVarying(qualifier);
+ // We're not checking whether the uniform location is in range here since that depends on
+ // the type of the variable.
+ // The type can only be fully determined for non-empty declarations.
+ }
+ if (!canHaveLocation)
+ {
+ checkLocationIsNotSpecified(location, layoutQualifier);
+ }
+}
+
+void TParseContext::atomicCounterQualifierErrorCheck(const TPublicType &publicType,
+ const TSourceLoc &location)
+{
+ if (publicType.precision != EbpHigh)
+ {
+ error(location, "Can only be highp", "atomic counter");
+ }
+ // dEQP enforces compile error if location is specified. See uniform_location.test.
+ if (publicType.layoutQualifier.location != -1)
+ {
+ error(location, "location must not be set for atomic_uint", "layout");
+ }
+ if (publicType.layoutQualifier.binding == -1)
+ {
+ error(location, "no binding specified", "atomic counter");
+ }
+}
+
+void TParseContext::emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location)
+{
+ if (type.isUnsizedArray())
+ {
+ // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an
+ // error. It is assumed that this applies to empty declarations as well.
+ error(location, "empty array declaration needs to specify a size", "");
+ }
+
+ if (type.getQualifier() != EvqFragmentOut)
+ {
+ checkIndexIsNotSpecified(location, type.getLayoutQualifier().index);
+ }
+}
+
+// These checks are done for all declarations that are non-empty. They're done for non-empty
+// declarations starting a declarator list, and declarators that follow an empty declaration.
+void TParseContext::nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation)
+{
+ switch (publicType.qualifier)
+ {
+ case EvqVaryingIn:
+ case EvqVaryingOut:
+ case EvqAttribute:
+ case EvqVertexIn:
+ case EvqFragmentOut:
+ case EvqFragmentInOut:
+ case EvqComputeIn:
+ if (publicType.getBasicType() == EbtStruct)
+ {
+ error(identifierLocation, "cannot be used with a structure",
+ getQualifierString(publicType.qualifier));
+ return;
+ }
+ break;
+ case EvqBuffer:
+ if (publicType.getBasicType() != EbtInterfaceBlock)
+ {
+ error(identifierLocation,
+ "cannot declare buffer variables at global scope(outside a block)",
+ getQualifierString(publicType.qualifier));
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+ std::string reason(getBasicString(publicType.getBasicType()));
+ reason += "s must be uniform";
+ if (publicType.qualifier != EvqUniform &&
+ !checkIsNotOpaqueType(identifierLocation, publicType.typeSpecifierNonArray, reason.c_str()))
+ {
+ return;
+ }
+
+ if ((publicType.qualifier != EvqTemporary && publicType.qualifier != EvqGlobal &&
+ publicType.qualifier != EvqConst) &&
+ publicType.getBasicType() == EbtYuvCscStandardEXT)
+ {
+ error(identifierLocation, "cannot be used with a yuvCscStandardEXT",
+ getQualifierString(publicType.qualifier));
+ return;
+ }
+
+ if (mShaderVersion >= 310 && publicType.qualifier == EvqUniform)
+ {
+ // Valid uniform declarations can't be unsized arrays since uniforms can't be initialized.
+ // But invalid shaders may still reach here with an unsized array declaration.
+ TType type(publicType);
+ if (!type.isUnsizedArray())
+ {
+ checkUniformLocationInRange(identifierLocation, type.getLocationCount(),
+ publicType.layoutQualifier);
+ }
+ }
+
+ if (mShaderVersion >= 300 && publicType.qualifier == EvqVertexIn)
+ {
+ // Valid vertex input declarations can't be unsized arrays since they can't be initialized.
+ // But invalid shaders may still reach here with an unsized array declaration.
+ TType type(publicType);
+ if (!type.isUnsizedArray())
+ {
+ checkAttributeLocationInRange(identifierLocation, type.getLocationCount(),
+ publicType.layoutQualifier);
+ }
+ }
+
+ // check for layout qualifier issues
+ const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
+
+ if (IsImage(publicType.getBasicType()))
+ {
+
+ switch (layoutQualifier.imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ case EiifRGBA8:
+ case EiifRGBA8_SNORM:
+ if (!IsFloatImage(publicType.getBasicType()))
+ {
+ error(identifierLocation,
+ "internal image format requires a floating image type",
+ getBasicString(publicType.getBasicType()));
+ return;
+ }
+ break;
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ if (!IsIntegerImage(publicType.getBasicType()))
+ {
+ error(identifierLocation,
+ "internal image format requires an integer image type",
+ getBasicString(publicType.getBasicType()));
+ return;
+ }
+ break;
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ if (!IsUnsignedImage(publicType.getBasicType()))
+ {
+ error(identifierLocation,
+ "internal image format requires an unsigned image type",
+ getBasicString(publicType.getBasicType()));
+ return;
+ }
+ break;
+ case EiifUnspecified:
+ error(identifierLocation, "layout qualifier", "No image internal format specified");
+ return;
+ default:
+ error(identifierLocation, "layout qualifier", "unrecognized token");
+ return;
+ }
+
+ // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
+ switch (layoutQualifier.imageInternalFormat)
+ {
+ case EiifR32F:
+ case EiifR32I:
+ case EiifR32UI:
+ break;
+ default:
+ if (!publicType.memoryQualifier.readonly && !publicType.memoryQualifier.writeonly)
+ {
+ error(identifierLocation, "layout qualifier",
+ "Except for images with the r32f, r32i and r32ui format qualifiers, "
+ "image variables must be qualified readonly and/or writeonly");
+ return;
+ }
+ break;
+ }
+ }
+ else if (IsPixelLocal(publicType.getBasicType()))
+ {
+ if (getShaderType() != GL_FRAGMENT_SHADER)
+ {
+ error(identifierLocation,
+ "undefined use of pixel local storage outside a fragment shader",
+ getBasicString(publicType.getBasicType()));
+ return;
+ }
+ switch (layoutQualifier.imageInternalFormat)
+ {
+ case EiifR32F:
+ case EiifRGBA8:
+ if (publicType.getBasicType() != EbtPixelLocalANGLE)
+ {
+ error(identifierLocation, "pixel local storage format requires pixelLocalANGLE",
+ getImageInternalFormatString(layoutQualifier.imageInternalFormat));
+ }
+ break;
+ case EiifRGBA8I:
+ if (publicType.getBasicType() != EbtIPixelLocalANGLE)
+ {
+ error(identifierLocation,
+ "pixel local storage format requires ipixelLocalANGLE",
+ getImageInternalFormatString(layoutQualifier.imageInternalFormat));
+ }
+ break;
+ case EiifR32UI:
+ case EiifRGBA8UI:
+ if (publicType.getBasicType() != EbtUPixelLocalANGLE)
+ {
+ error(identifierLocation,
+ "pixel local storage format requires upixelLocalANGLE",
+ getImageInternalFormatString(layoutQualifier.imageInternalFormat));
+ }
+ break;
+ case EiifR32I:
+ case EiifRGBA8_SNORM:
+ case EiifRGBA16F:
+ case EiifRGBA32F:
+ case EiifRGBA16I:
+ case EiifRGBA32I:
+ case EiifRGBA16UI:
+ case EiifRGBA32UI:
+ default:
+ ASSERT(!IsValidWithPixelLocalStorage(layoutQualifier.imageInternalFormat));
+ error(identifierLocation, "illegal pixel local storage format",
+ getImageInternalFormatString(layoutQualifier.imageInternalFormat));
+ break;
+ case EiifUnspecified:
+ error(identifierLocation, "pixel local storage requires a format specifier",
+ "layout qualifier");
+ break;
+ }
+ checkMemoryQualifierIsNotSpecified(publicType.memoryQualifier, identifierLocation);
+ checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
+ }
+ else
+ {
+ checkInternalFormatIsNotSpecified(identifierLocation, layoutQualifier.imageInternalFormat);
+ checkMemoryQualifierIsNotSpecified(publicType.memoryQualifier, identifierLocation);
+ }
+
+ if (IsAtomicCounter(publicType.getBasicType()))
+ {
+ atomicCounterQualifierErrorCheck(publicType, identifierLocation);
+ }
+ else
+ {
+ checkOffsetIsNotSpecified(identifierLocation, layoutQualifier.offset);
+ }
+}
+
+void TParseContext::checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type)
+{
+ TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
+ // Note that the ESSL 3.10 section 4.4.5 is not particularly clear on how the binding qualifier
+ // on arrays of arrays should be handled. We interpret the spec so that the binding value is
+ // incremented for each element of the innermost nested arrays. This is in line with how arrays
+ // of arrays of blocks are specified to behave in GLSL 4.50 and a conservative interpretation
+ // when it comes to which shaders are accepted by the compiler.
+ int arrayTotalElementCount = type.getArraySizeProduct();
+ if (IsPixelLocal(type.getBasicType()))
+ {
+ checkPixelLocalStorageBindingIsValid(identifierLocation, type);
+ }
+ else if (mShaderVersion < 310)
+ {
+ checkBindingIsNotSpecified(identifierLocation, layoutQualifier.binding);
+ }
+ else if (IsImage(type.getBasicType()))
+ {
+ checkImageBindingIsValid(identifierLocation, layoutQualifier.binding,
+ arrayTotalElementCount);
+ }
+ else if (IsSampler(type.getBasicType()))
+ {
+ checkSamplerBindingIsValid(identifierLocation, layoutQualifier.binding,
+ arrayTotalElementCount);
+ }
+ else if (IsAtomicCounter(type.getBasicType()))
+ {
+ checkAtomicCounterBindingIsValid(identifierLocation, layoutQualifier.binding);
+ }
+ else
+ {
+ ASSERT(!IsOpaqueType(type.getBasicType()));
+ checkBindingIsNotSpecified(identifierLocation, layoutQualifier.binding);
+ }
+}
+
+void TParseContext::checkCanUseLayoutQualifier(const TSourceLoc &location)
+{
+ constexpr std::array<TExtension, 4u> extensions{
+ {TExtension::EXT_shader_framebuffer_fetch,
+ TExtension::EXT_shader_framebuffer_fetch_non_coherent,
+ TExtension::KHR_blend_equation_advanced, TExtension::ANGLE_shader_pixel_local_storage}};
+ if (getShaderVersion() < 300 && !checkCanUseOneOfExtensions(location, extensions))
+ {
+ error(location, "qualifier supported in GLSL ES 3.00 and above only", "layout");
+ }
+}
+
+bool TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location,
+ const ImmutableString &layoutQualifierName,
+ int versionRequired)
+{
+
+ if (mShaderVersion < versionRequired)
+ {
+ error(location, "invalid layout qualifier: not supported", layoutQualifierName);
+ return false;
+ }
+ return true;
+}
+
+bool TParseContext::checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
+ const TLayoutQualifier &layoutQualifier)
+{
+ const sh::WorkGroupSize &localSize = layoutQualifier.localSize;
+ for (size_t i = 0u; i < localSize.size(); ++i)
+ {
+ if (localSize[i] != -1)
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with 'in' in a compute shader "
+ "global layout declaration",
+ getWorkGroupSizeString(i));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void TParseContext::checkInternalFormatIsNotSpecified(const TSourceLoc &location,
+ TLayoutImageInternalFormat internalFormat)
+{
+ if (internalFormat != EiifUnspecified)
+ {
+ if (mShaderVersion < 310)
+ {
+ if (IsValidWithPixelLocalStorage(internalFormat))
+ {
+ error(location,
+ "invalid layout qualifier: not supported before GLSL ES 3.10, except pixel "
+ "local storage",
+ getImageInternalFormatString(internalFormat));
+ }
+ else
+ {
+ error(location, "invalid layout qualifier: not supported before GLSL ES 3.10",
+ getImageInternalFormatString(internalFormat));
+ }
+ }
+ else
+ {
+ if (IsValidWithPixelLocalStorage(internalFormat))
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with images or pixel local "
+ "storage ",
+ getImageInternalFormatString(internalFormat));
+ }
+ else
+ {
+ error(location, "invalid layout qualifier: only valid when used with images",
+ getImageInternalFormatString(internalFormat));
+ }
+ }
+ }
+}
+
+void TParseContext::checkIndexIsNotSpecified(const TSourceLoc &location, int index)
+{
+ if (index != -1)
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with a fragment shader output in "
+ "ESSL version >= 3.00 and EXT_blend_func_extended is enabled",
+ "index");
+ }
+}
+
+void TParseContext::checkBindingIsNotSpecified(const TSourceLoc &location, int binding)
+{
+ if (binding != -1)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with pixel local storage",
+ "binding");
+ }
+ else
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with opaque types or blocks",
+ "binding");
+ }
+ }
+}
+
+void TParseContext::checkOffsetIsNotSpecified(const TSourceLoc &location, int offset)
+{
+ if (offset != -1)
+ {
+ error(location, "invalid layout qualifier: only valid when used with atomic counters",
+ "offset");
+ }
+}
+
+void TParseContext::checkImageBindingIsValid(const TSourceLoc &location,
+ int binding,
+ int arrayTotalElementCount)
+{
+ // Expects arraySize to be 1 when setting binding for only a single variable.
+ if (binding >= 0 && binding + arrayTotalElementCount > mMaxImageUnits)
+ {
+ error(location, "image binding greater than gl_MaxImageUnits", "binding");
+ }
+}
+
+void TParseContext::checkSamplerBindingIsValid(const TSourceLoc &location,
+ int binding,
+ int arrayTotalElementCount)
+{
+ // Expects arraySize to be 1 when setting binding for only a single variable.
+ if (binding >= 0 && binding + arrayTotalElementCount > mMaxCombinedTextureImageUnits)
+ {
+ error(location, "sampler binding greater than maximum texture units", "binding");
+ }
+}
+
+void TParseContext::checkBlockBindingIsValid(const TSourceLoc &location,
+ const TQualifier &qualifier,
+ int binding,
+ int arraySize)
+{
+ int size = (arraySize == 0 ? 1 : arraySize);
+ if (qualifier == EvqUniform)
+ {
+ if (binding + size > mMaxUniformBufferBindings)
+ {
+ error(location, "uniform block binding greater than MAX_UNIFORM_BUFFER_BINDINGS",
+ "binding");
+ }
+ }
+ else if (qualifier == EvqBuffer)
+ {
+ if (binding + size > mMaxShaderStorageBufferBindings)
+ {
+ error(location,
+ "shader storage block binding greater than MAX_SHADER_STORAGE_BUFFER_BINDINGS",
+ "binding");
+ }
+ }
+}
+void TParseContext::checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding)
+{
+ if (binding >= mMaxAtomicCounterBindings)
+ {
+ error(location, "atomic counter binding greater than gl_MaxAtomicCounterBindings",
+ "binding");
+ }
+}
+
+void TParseContext::checkPixelLocalStorageBindingIsValid(const TSourceLoc &location,
+ const TType &type)
+{
+ TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
+ if (type.isArray())
+ {
+ // PLS is not allowed in arrays.
+ // TODO(anglebug.com/7279): Consider allowing this once more backends are implemented.
+ error(location, "pixel local storage handles cannot be aggregated in arrays", "array");
+ }
+ else if (layoutQualifier.binding < 0)
+ {
+ error(location, "pixel local storage requires a binding index", "layout qualifier");
+ }
+ // TODO(anglebug.com/7279):
+ // else if (binding >= GL_MAX_LOCAL_STORAGE_PLANES_ANGLE)
+ // {
+ // }
+ else if (mPLSBindings.find(layoutQualifier.binding) != mPLSBindings.end())
+ {
+ error(location, "duplicate pixel local storage binding index",
+ std::to_string(layoutQualifier.binding).c_str());
+ }
+ else
+ {
+ mPLSBindings[layoutQualifier.binding] = layoutQualifier.imageInternalFormat;
+ // "mPLSBindings" is how we know whether pixel local storage uniforms have been declared, so
+ // flush the queue of potential errors once mPLSBindings isn't empty.
+ if (!mPLSPotentialErrors.empty())
+ {
+ for (const auto &[loc, op] : mPLSPotentialErrors)
+ {
+ errorIfPLSDeclared(loc, op);
+ }
+ mPLSPotentialErrors.clear();
+ }
+ }
+}
+
+void TParseContext::checkUniformLocationInRange(const TSourceLoc &location,
+ int objectLocationCount,
+ const TLayoutQualifier &layoutQualifier)
+{
+ int loc = layoutQualifier.location;
+ if (loc >= 0) // Shader-specified location
+ {
+ if (loc >= mMaxUniformLocations || objectLocationCount > mMaxUniformLocations ||
+ static_cast<unsigned int>(loc) + static_cast<unsigned int>(objectLocationCount) >
+ static_cast<unsigned int>(mMaxUniformLocations))
+ {
+ error(location, "Uniform location out of range", "location");
+ }
+ }
+}
+
+void TParseContext::checkAttributeLocationInRange(const TSourceLoc &location,
+ int objectLocationCount,
+ const TLayoutQualifier &layoutQualifier)
+{
+ int loc = layoutQualifier.location;
+ if (loc >= 0) // Shader-specified location
+ {
+ if (loc >= mMaxVertexAttribs || objectLocationCount > mMaxVertexAttribs ||
+ static_cast<unsigned int>(loc) + static_cast<unsigned int>(objectLocationCount) >
+ static_cast<unsigned int>(mMaxVertexAttribs))
+ {
+ error(location, "Attribute location out of range", "location");
+ }
+ }
+}
+
+void TParseContext::checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv)
+{
+ if (yuv != false)
+ {
+ error(location, "invalid layout qualifier: only valid on program outputs", "yuv");
+ }
+}
+
+void TParseContext::checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc &location,
+ bool earlyFragmentTests)
+{
+ if (earlyFragmentTests != false)
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with 'in' in a fragment shader",
+ "early_fragment_tests");
+ }
+}
+
+void TParseContext::checkNoncoherentIsSpecified(const TSourceLoc &location, bool noncoherent)
+{
+ if (noncoherent == false)
+ {
+ error(location,
+ "'noncoherent' qualifier must be used when "
+ "GL_EXT_shader_framebuffer_fetch_non_coherent extension is used",
+ "noncoherent");
+ }
+}
+
+void TParseContext::checkNoncoherentIsNotSpecified(const TSourceLoc &location, bool noncoherent)
+{
+ if (noncoherent != false)
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with 'gl_LastFragData' or the "
+ "variable decorated with 'inout' in a fragment shader",
+ "noncoherent");
+ }
+}
+
+void TParseContext::checkTCSOutVarIndexIsValid(TIntermBinary *binaryExpression,
+ const TSourceLoc &location)
+{
+ ASSERT(binaryExpression->getOp() == EOpIndexIndirect ||
+ binaryExpression->getOp() == EOpIndexDirect);
+ const TIntermSymbol *intermSymbol = binaryExpression->getRight()->getAsSymbolNode();
+ if ((intermSymbol == nullptr) || (intermSymbol->getName() != "gl_InvocationID"))
+ {
+ error(location,
+ "tessellation-control per-vertex output l-value must be indexed with "
+ "gl_InvocationID",
+ "[");
+ }
+}
+
+void TParseContext::functionCallRValueLValueErrorCheck(const TFunction *fnCandidate,
+ TIntermAggregate *fnCall)
+{
+ for (size_t i = 0; i < fnCandidate->getParamCount(); ++i)
+ {
+ TQualifier qual = fnCandidate->getParam(i)->getType().getQualifier();
+ TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped();
+ bool argumentIsRead = (IsQualifierUnspecified(qual) || qual == EvqParamIn ||
+ qual == EvqParamInOut || qual == EvqParamConst);
+ if (argumentIsRead)
+ {
+ markStaticReadIfSymbol(argument);
+ if (!IsImage(argument->getBasicType()))
+ {
+ if (argument->getMemoryQualifier().writeonly)
+ {
+ error(argument->getLine(),
+ "Writeonly value cannot be passed for 'in' or 'inout' parameters.",
+ fnCall->functionName());
+ return;
+ }
+ }
+ }
+ if (qual == EvqParamOut || qual == EvqParamInOut)
+ {
+ if (!checkCanBeLValue(argument->getLine(), "assign", argument))
+ {
+ error(argument->getLine(),
+ "Constant value cannot be passed for 'out' or 'inout' parameters.",
+ fnCall->functionName());
+ return;
+ }
+ }
+ }
+}
+
+void TParseContext::checkInvariantVariableQualifier(bool invariant,
+ const TQualifier qualifier,
+ const TSourceLoc &invariantLocation)
+{
+ if (!invariant)
+ return;
+
+ if (mShaderVersion < 300)
+ {
+ // input variables in the fragment shader can be also qualified as invariant
+ if (!sh::CanBeInvariantESSL1(qualifier))
+ {
+ error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
+ }
+ }
+ else
+ {
+ if (!sh::CanBeInvariantESSL3OrGreater(qualifier))
+ {
+ error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
+ }
+ }
+}
+
+void TParseContext::checkAdvancedBlendEquationsNotSpecified(
+ const TSourceLoc &location,
+ const AdvancedBlendEquations &advancedBlendEquations,
+ const TQualifier &qualifier)
+{
+ if (advancedBlendEquations.any() && qualifier != EvqFragmentOut)
+ {
+ error(location,
+ "invalid layout qualifier: blending equation qualifiers are only permitted on the "
+ "fragment 'out' qualifier ",
+ "blend_support_qualifier");
+ }
+}
+
+bool TParseContext::isExtensionEnabled(TExtension extension) const
+{
+ return IsExtensionEnabled(extensionBehavior(), extension);
+}
+
+void TParseContext::handleExtensionDirective(const TSourceLoc &loc,
+ const char *extName,
+ const char *behavior)
+{
+ angle::pp::SourceLocation srcLoc;
+ srcLoc.file = loc.first_file;
+ srcLoc.line = loc.first_line;
+ mDirectiveHandler.handleExtension(srcLoc, extName, behavior);
+}
+
+void TParseContext::handlePragmaDirective(const TSourceLoc &loc,
+ const char *name,
+ const char *value,
+ bool stdgl)
+{
+ angle::pp::SourceLocation srcLoc;
+ srcLoc.file = loc.first_file;
+ srcLoc.line = loc.first_line;
+ mDirectiveHandler.handlePragma(srcLoc, name, value, stdgl);
+}
+
+sh::WorkGroupSize TParseContext::getComputeShaderLocalSize() const
+{
+ sh::WorkGroupSize result(-1);
+ for (size_t i = 0u; i < result.size(); ++i)
+ {
+ if (mComputeShaderLocalSizeDeclared && mComputeShaderLocalSize[i] == -1)
+ {
+ result[i] = 1;
+ }
+ else
+ {
+ result[i] = mComputeShaderLocalSize[i];
+ }
+ }
+ return result;
+}
+
+TIntermConstantUnion *TParseContext::addScalarLiteral(const TConstantUnion *constantUnion,
+ const TSourceLoc &line)
+{
+ TIntermConstantUnion *node = new TIntermConstantUnion(
+ constantUnion, TType(constantUnion->getType(), EbpUndefined, EvqConst));
+ node->setLine(line);
+ return node;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+// Non-Errors.
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
+ const ImmutableString &name,
+ const TSymbol *symbol)
+{
+ if (!symbol)
+ {
+ error(location, "undeclared identifier", name);
+ return nullptr;
+ }
+
+ if (!symbol->isVariable())
+ {
+ error(location, "variable expected", name);
+ return nullptr;
+ }
+
+ const TVariable *variable = static_cast<const TVariable *>(symbol);
+
+ if (!variable->extensions().empty() && variable->extensions()[0] != TExtension::UNDEFINED)
+ {
+ checkCanUseOneOfExtensions(location, variable->extensions());
+ }
+
+ // GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables
+ if (getShaderType() == GL_COMPUTE_SHADER && !mComputeShaderLocalSizeDeclared &&
+ variable->getType().getQualifier() == EvqWorkGroupSize)
+ {
+ error(location,
+ "It is an error to use gl_WorkGroupSize before declaring the local group size",
+ "gl_WorkGroupSize");
+ }
+
+ // If EXT_shader_framebuffer_fetch_non_coherent is used, gl_LastFragData should be decorated
+ // with 'layout(noncoherent)' EXT_shader_framebuffer_fetch_non_coherent spec: "Unless the
+ // GL_EXT_shader_framebuffer_fetch extension has been enabled in addition, it's an error to use
+ // gl_LastFragData if it hasn't been explicitly redeclared with layout(noncoherent)."
+ if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent) &&
+ !isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) &&
+ variable->getType().getQualifier() == EvqLastFragData)
+ {
+ checkNoncoherentIsSpecified(location, variable->getType().getLayoutQualifier().noncoherent);
+ }
+ return variable;
+}
+
+TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
+ const ImmutableString &name,
+ const TSymbol *symbol)
+{
+ const TVariable *variable = getNamedVariable(location, name, symbol);
+
+ if (!variable)
+ {
+ TIntermTyped *node = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
+ node->setLine(location);
+ return node;
+ }
+
+ const TType &variableType = variable->getType();
+ TIntermTyped *node = nullptr;
+
+ if (variable->getConstPointer() && variableType.canReplaceWithConstantUnion())
+ {
+ const TConstantUnion *constArray = variable->getConstPointer();
+ node = new TIntermConstantUnion(constArray, variableType);
+ }
+ else if (variableType.getQualifier() == EvqWorkGroupSize && mComputeShaderLocalSizeDeclared)
+ {
+ // gl_WorkGroupSize can be used to size arrays according to the ESSL 3.10.4 spec, so it
+ // needs to be added to the AST as a constant and not as a symbol.
+ sh::WorkGroupSize workGroupSize = getComputeShaderLocalSize();
+ TConstantUnion *constArray = new TConstantUnion[3];
+ for (size_t i = 0; i < 3; ++i)
+ {
+ constArray[i].setUConst(static_cast<unsigned int>(workGroupSize[i]));
+ }
+
+ ASSERT(variableType.getBasicType() == EbtUInt);
+ ASSERT(variableType.getObjectSize() == 3);
+
+ TType type(variableType);
+ type.setQualifier(EvqConst);
+ node = new TIntermConstantUnion(constArray, type);
+ }
+ else if ((mGeometryShaderInputPrimitiveType != EptUndefined) &&
+ (variableType.getQualifier() == EvqPerVertexIn))
+ {
+ ASSERT(symbolTable.getGlInVariableWithArraySize() != nullptr);
+ node = new TIntermSymbol(symbolTable.getGlInVariableWithArraySize());
+ }
+ else
+ {
+ node = new TIntermSymbol(variable);
+ }
+ ASSERT(node != nullptr);
+ node->setLine(location);
+ return node;
+}
+
+void TParseContext::adjustRedeclaredBuiltInType(const ImmutableString &identifier, TType *type)
+{
+ if (identifier == "gl_ClipDistance")
+ {
+ type->setQualifier(EvqClipDistance);
+ }
+ else if (identifier == "gl_CullDistance")
+ {
+ type->setQualifier(EvqCullDistance);
+ }
+ else if (identifier == "gl_LastFragData")
+ {
+ type->setQualifier(EvqLastFragData);
+ }
+}
+
+// Initializers show up in several places in the grammar. Have one set of
+// code to handle them here.
+//
+// Returns true on success.
+bool TParseContext::executeInitializer(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ TType *type,
+ TIntermTyped *initializer,
+ TIntermBinary **initNode)
+{
+ ASSERT(initNode != nullptr);
+ ASSERT(*initNode == nullptr);
+
+ if (type->isUnsizedArray())
+ {
+ // In case initializer is not an array or type has more dimensions than initializer, this
+ // will default to setting array sizes to 1. We have not checked yet whether the initializer
+ // actually is an array or not. Having a non-array initializer for an unsized array will
+ // result in an error later, so we don't generate an error message here.
+ type->sizeUnsizedArrays(initializer->getType().getArraySizes());
+ }
+
+ const TQualifier qualifier = type->getQualifier();
+
+ bool constError = false;
+ if (qualifier == EvqConst)
+ {
+ if (EvqConst != initializer->getType().getQualifier())
+ {
+ TInfoSinkBase reasonStream;
+ reasonStream << "assigning non-constant to '" << *type << "'";
+ error(line, reasonStream.c_str(), "=");
+
+ // We're still going to declare the variable to avoid extra error messages.
+ type->setQualifier(EvqTemporary);
+ constError = true;
+ }
+ }
+
+ TVariable *variable = nullptr;
+ if (!declareVariable(line, identifier, type, &variable))
+ {
+ return false;
+ }
+
+ if (constError)
+ {
+ return false;
+ }
+
+ bool nonConstGlobalInitializers =
+ IsExtensionEnabled(mDirectiveHandler.extensionBehavior(),
+ TExtension::EXT_shader_non_constant_global_initializers);
+ bool globalInitWarning = false;
+ if (symbolTable.atGlobalLevel() &&
+ !ValidateGlobalInitializer(initializer, mShaderVersion, sh::IsWebGLBasedSpec(mShaderSpec),
+ nonConstGlobalInitializers, &globalInitWarning))
+ {
+ // Error message does not completely match behavior with ESSL 1.00, but
+ // we want to steer developers towards only using constant expressions.
+ error(line, "global variable initializers must be constant expressions", "=");
+ return false;
+ }
+ if (globalInitWarning)
+ {
+ warning(
+ line,
+ "global variable initializers should be constant expressions "
+ "(uniforms and globals are allowed in global initializers for legacy compatibility)",
+ "=");
+ }
+
+ // identifier must be of type constant, a global, or a temporary
+ if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst))
+ {
+ error(line, " cannot initialize this type of qualifier ",
+ variable->getType().getQualifierString());
+ return false;
+ }
+
+ TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
+ intermSymbol->setLine(line);
+
+ if (!binaryOpCommonCheck(EOpInitialize, intermSymbol, initializer, line))
+ {
+ assignError(line, "=", variable->getType(), initializer->getType());
+ return false;
+ }
+
+ if (qualifier == EvqConst)
+ {
+ // Save the constant folded value to the variable if possible.
+ const TConstantUnion *constArray = initializer->getConstantValue();
+ if (constArray)
+ {
+ variable->shareConstPointer(constArray);
+ if (initializer->getType().canReplaceWithConstantUnion())
+ {
+ ASSERT(*initNode == nullptr);
+ return true;
+ }
+ }
+ }
+
+ *initNode = new TIntermBinary(EOpInitialize, intermSymbol, initializer);
+ markStaticReadIfSymbol(initializer);
+ (*initNode)->setLine(line);
+ return true;
+}
+
+TIntermNode *TParseContext::addConditionInitializer(const TPublicType &pType,
+ const ImmutableString &identifier,
+ TIntermTyped *initializer,
+ const TSourceLoc &loc)
+{
+ checkIsScalarBool(loc, pType);
+ TIntermBinary *initNode = nullptr;
+ TType *type = new TType(pType);
+ if (executeInitializer(loc, identifier, type, initializer, &initNode))
+ {
+ // The initializer is valid. The init condition needs to have a node - either the
+ // initializer node, or a constant node in case the initialized variable is const and won't
+ // be recorded in the AST.
+ if (initNode == nullptr)
+ {
+ return initializer;
+ }
+ else
+ {
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->appendDeclarator(initNode);
+ return declaration;
+ }
+ }
+ return nullptr;
+}
+
+TIntermNode *TParseContext::addLoop(TLoopType type,
+ TIntermNode *init,
+ TIntermNode *cond,
+ TIntermTyped *expr,
+ TIntermNode *body,
+ const TSourceLoc &line)
+{
+ TIntermNode *node = nullptr;
+ TIntermTyped *typedCond = nullptr;
+ if (cond)
+ {
+ markStaticReadIfSymbol(cond);
+ typedCond = cond->getAsTyped();
+ }
+ if (expr)
+ {
+ markStaticReadIfSymbol(expr);
+ }
+ // In case the loop body was not parsed as a block and contains a statement that simply refers
+ // to a variable, we need to mark it as statically used.
+ if (body)
+ {
+ markStaticReadIfSymbol(body);
+ }
+ if (cond == nullptr || typedCond)
+ {
+ if (type == ELoopDoWhile && typedCond)
+ {
+ checkIsScalarBool(line, typedCond);
+ }
+ // In the case of other loops, it was checked before that the condition is a scalar boolean.
+ ASSERT(mDiagnostics->numErrors() > 0 || typedCond == nullptr ||
+ (typedCond->getBasicType() == EbtBool && !typedCond->isArray() &&
+ !typedCond->isVector()));
+
+ node = new TIntermLoop(type, init, typedCond, expr, EnsureBlock(body));
+ node->setLine(line);
+ return node;
+ }
+
+ ASSERT(type != ELoopDoWhile);
+
+ TIntermDeclaration *declaration = cond->getAsDeclarationNode();
+ ASSERT(declaration);
+ TIntermBinary *declarator = declaration->getSequence()->front()->getAsBinaryNode();
+ ASSERT(declarator->getLeft()->getAsSymbolNode());
+
+ // The condition is a declaration. In the AST representation we don't support declarations as
+ // loop conditions. Wrap the loop to a block that declares the condition variable and contains
+ // the loop.
+ TIntermBlock *block = new TIntermBlock();
+
+ TIntermDeclaration *declareCondition = new TIntermDeclaration();
+ declareCondition->appendDeclarator(declarator->getLeft()->deepCopy());
+ block->appendStatement(declareCondition);
+
+ TIntermBinary *conditionInit = new TIntermBinary(EOpAssign, declarator->getLeft()->deepCopy(),
+ declarator->getRight()->deepCopy());
+ TIntermLoop *loop = new TIntermLoop(type, init, conditionInit, expr, EnsureBlock(body));
+ block->appendStatement(loop);
+ loop->setLine(line);
+ block->setLine(line);
+ return block;
+}
+
+TIntermNode *TParseContext::addIfElse(TIntermTyped *cond,
+ TIntermNodePair code,
+ const TSourceLoc &loc)
+{
+ bool isScalarBool = checkIsScalarBool(loc, cond);
+ // In case the conditional statements were not parsed as blocks and contain a statement that
+ // simply refers to a variable, we need to mark them as statically used.
+ if (code.node1)
+ {
+ markStaticReadIfSymbol(code.node1);
+ }
+ if (code.node2)
+ {
+ markStaticReadIfSymbol(code.node2);
+ }
+
+ // For compile time constant conditions, prune the code now.
+ if (isScalarBool && cond->getAsConstantUnion())
+ {
+ if (cond->getAsConstantUnion()->getBConst(0) == true)
+ {
+ return EnsureBlock(code.node1);
+ }
+ else
+ {
+ return EnsureBlock(code.node2);
+ }
+ }
+
+ TIntermIfElse *node = new TIntermIfElse(cond, EnsureBlock(code.node1), EnsureBlock(code.node2));
+ markStaticReadIfSymbol(cond);
+ node->setLine(loc);
+
+ return node;
+}
+
+void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier)
+{
+ checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision,
+ typeSpecifier->getBasicType());
+
+ if (mShaderVersion < 300 && typeSpecifier->isArray())
+ {
+ error(typeSpecifier->getLine(), "not supported", "first-class array");
+ typeSpecifier->clearArrayness();
+ }
+}
+
+TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TPublicType &typeSpecifier)
+{
+ TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
+
+ TPublicType returnType = typeSpecifier;
+ returnType.qualifier = typeQualifier.qualifier;
+ returnType.invariant = typeQualifier.invariant;
+ returnType.precise = typeQualifier.precise;
+ returnType.layoutQualifier = typeQualifier.layoutQualifier;
+ returnType.memoryQualifier = typeQualifier.memoryQualifier;
+ returnType.precision = typeSpecifier.precision;
+
+ if (typeQualifier.precision != EbpUndefined)
+ {
+ returnType.precision = typeQualifier.precision;
+ }
+
+ checkPrecisionSpecified(typeSpecifier.getLine(), returnType.precision,
+ typeSpecifier.getBasicType());
+
+ checkInvariantVariableQualifier(returnType.invariant, returnType.qualifier,
+ typeSpecifier.getLine());
+
+ checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), returnType.layoutQualifier);
+
+ checkEarlyFragmentTestsIsNotSpecified(typeSpecifier.getLine(),
+ returnType.layoutQualifier.earlyFragmentTests);
+
+ if (returnType.qualifier == EvqSampleIn || returnType.qualifier == EvqSampleOut)
+ {
+ mSampleQualifierSpecified = true;
+ }
+
+ if (mShaderVersion < 300)
+ {
+ if (typeSpecifier.isArray())
+ {
+ error(typeSpecifier.getLine(), "not supported", "first-class array");
+ returnType.clearArrayness();
+ }
+
+ if (returnType.qualifier == EvqAttribute &&
+ (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
+ {
+ error(typeSpecifier.getLine(), "cannot be bool or int",
+ getQualifierString(returnType.qualifier));
+ }
+
+ if ((returnType.qualifier == EvqVaryingIn || returnType.qualifier == EvqVaryingOut) &&
+ (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
+ {
+ error(typeSpecifier.getLine(), "cannot be bool or int",
+ getQualifierString(returnType.qualifier));
+ }
+ }
+ else
+ {
+ if (!returnType.layoutQualifier.isEmpty())
+ {
+ checkIsAtGlobalLevel(typeSpecifier.getLine(), "layout");
+ }
+ if (sh::IsVarying(returnType.qualifier) || returnType.qualifier == EvqVertexIn ||
+ returnType.qualifier == EvqFragmentOut || returnType.qualifier == EvqFragmentInOut)
+ {
+ checkInputOutputTypeIsValidES3(returnType.qualifier, typeSpecifier,
+ typeSpecifier.getLine());
+ }
+ if (returnType.qualifier == EvqComputeIn)
+ {
+ error(typeSpecifier.getLine(), "'in' can be only used to specify the local group size",
+ "in");
+ }
+ }
+
+ return returnType;
+}
+
+void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
+ const TPublicType &type,
+ const TSourceLoc &qualifierLocation)
+{
+ // An input/output variable can never be bool or a sampler. Samplers are checked elsewhere.
+ if (type.getBasicType() == EbtBool)
+ {
+ error(qualifierLocation, "cannot be bool", getQualifierString(qualifier));
+ }
+
+ // Specific restrictions apply for vertex shader inputs and fragment shader outputs.
+ switch (qualifier)
+ {
+ case EvqVertexIn:
+ // ESSL 3.00 section 4.3.4
+ if (type.isArray())
+ {
+ error(qualifierLocation, "cannot be array", getQualifierString(qualifier));
+ }
+ // Vertex inputs with a struct type are disallowed in nonEmptyDeclarationErrorCheck
+ return;
+ case EvqFragmentOut:
+ case EvqFragmentInOut:
+ // ESSL 3.00 section 4.3.6
+ if (type.typeSpecifierNonArray.isMatrix())
+ {
+ error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier));
+ }
+ // Fragment outputs with a struct type are disallowed in nonEmptyDeclarationErrorCheck
+ return;
+ default:
+ break;
+ }
+
+ // Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of
+ // restrictions.
+ bool typeContainsIntegers =
+ (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt ||
+ type.isStructureContainingType(EbtInt) || type.isStructureContainingType(EbtUInt));
+ bool extendedShaderTypes = mShaderVersion >= 320 ||
+ isExtensionEnabled(TExtension::EXT_geometry_shader) ||
+ isExtensionEnabled(TExtension::OES_geometry_shader) ||
+ isExtensionEnabled(TExtension::EXT_tessellation_shader);
+ if (typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut &&
+ (!extendedShaderTypes || mShaderType == GL_FRAGMENT_SHADER))
+ {
+ error(qualifierLocation, "must use 'flat' interpolation here",
+ getQualifierString(qualifier));
+ }
+
+ if (type.getBasicType() == EbtStruct)
+ {
+ // ESSL 3.00 sections 4.3.4 and 4.3.6.
+ // These restrictions are only implied by the ESSL 3.00 spec, but
+ // the ESSL 3.10 spec lists these restrictions explicitly.
+ if (type.isArray())
+ {
+ error(qualifierLocation, "cannot be an array of structures",
+ getQualifierString(qualifier));
+ }
+ if (type.isStructureContainingArrays())
+ {
+ error(qualifierLocation, "cannot be a structure containing an array",
+ getQualifierString(qualifier));
+ }
+ if (type.isStructureContainingType(EbtStruct))
+ {
+ error(qualifierLocation, "cannot be a structure containing a structure",
+ getQualifierString(qualifier));
+ }
+ if (type.isStructureContainingType(EbtBool))
+ {
+ error(qualifierLocation, "cannot be a structure containing a bool",
+ getQualifierString(qualifier));
+ }
+ }
+}
+
+void TParseContext::checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier)
+{
+ if (qualifier.getType() == QtStorage)
+ {
+ const TStorageQualifierWrapper &storageQualifier =
+ static_cast<const TStorageQualifierWrapper &>(qualifier);
+ if (!declaringFunction() && storageQualifier.getQualifier() != EvqConst &&
+ !symbolTable.atGlobalLevel())
+ {
+ error(storageQualifier.getLine(),
+ "Local variables can only use the const storage qualifier.",
+ storageQualifier.getQualifierString());
+ }
+ }
+}
+
+void TParseContext::checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
+ const TSourceLoc &location)
+{
+ const std::string reason(
+ "Only allowed with shader storage blocks, variables declared within shader storage blocks "
+ "and variables declared as image types.");
+ if (memoryQualifier.readonly)
+ {
+ error(location, reason.c_str(), "readonly");
+ }
+ if (memoryQualifier.writeonly)
+ {
+ error(location, reason.c_str(), "writeonly");
+ }
+ if (memoryQualifier.coherent)
+ {
+ error(location, reason.c_str(), "coherent");
+ }
+ if (memoryQualifier.restrictQualifier)
+ {
+ error(location, reason.c_str(), "restrict");
+ }
+ if (memoryQualifier.volatileQualifier)
+ {
+ error(location, reason.c_str(), "volatile");
+ }
+}
+
+// Make sure there is no offset overlapping, and store the newly assigned offset to "type" in
+// intermediate tree.
+void TParseContext::checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
+ const TSourceLoc &loc,
+ TType *type)
+{
+ const size_t size = type->isArray() ? kAtomicCounterArrayStride * type->getArraySizeProduct()
+ : kAtomicCounterSize;
+ TLayoutQualifier layoutQualifier = type->getLayoutQualifier();
+ auto &bindingState = mAtomicCounterBindingStates[layoutQualifier.binding];
+ int offset;
+ if (layoutQualifier.offset == -1 || forceAppend)
+ {
+ offset = bindingState.appendSpan(size);
+ }
+ else
+ {
+ offset = bindingState.insertSpan(layoutQualifier.offset, size);
+ }
+ if (offset == -1)
+ {
+ error(loc, "Offset overlapping", "atomic counter");
+ return;
+ }
+ layoutQualifier.offset = offset;
+ type->setLayoutQualifier(layoutQualifier);
+}
+
+void TParseContext::checkAtomicCounterOffsetAlignment(const TSourceLoc &location, const TType &type)
+{
+ TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
+
+ // OpenGL ES 3.1 Table 6.5, Atomic counter offset must be a multiple of 4
+ if (layoutQualifier.offset % 4 != 0)
+ {
+ error(location, "Offset must be multiple of 4", "atomic counter");
+ }
+}
+
+void TParseContext::checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
+ const ImmutableString &token,
+ TType *type)
+{
+ if (IsGeometryShaderInput(mShaderType, type->getQualifier()))
+ {
+ if (type->isArray() && type->getOutermostArraySize() == 0u)
+ {
+ // Set size for the unsized geometry shader inputs if they are declared after a valid
+ // input primitive declaration.
+ if (mGeometryShaderInputPrimitiveType != EptUndefined)
+ {
+ ASSERT(symbolTable.getGlInVariableWithArraySize() != nullptr);
+ type->sizeOutermostUnsizedArray(
+ symbolTable.getGlInVariableWithArraySize()->getType().getOutermostArraySize());
+ }
+ else
+ {
+ // [GLSL ES 3.2 SPEC Chapter 4.4.1.2]
+ // An input can be declared without an array size if there is a previous layout
+ // which specifies the size.
+ warning(location,
+ "Missing a valid input primitive declaration before declaring an unsized "
+ "array input",
+ "Deferred");
+ mDeferredArrayTypesToSize.push_back(type);
+ }
+ }
+ else if (type->isArray())
+ {
+ setGeometryShaderInputArraySize(type->getOutermostArraySize(), location);
+ }
+ else
+ {
+ error(location, "Geometry shader input variable must be declared as an array", token);
+ }
+ }
+}
+
+void TParseContext::checkTessellationShaderUnsizedArraysAndSetSize(const TSourceLoc &location,
+ const ImmutableString &token,
+ TType *type)
+{
+ TQualifier qualifier = type->getQualifier();
+ if (!IsTessellationControlShaderOutput(mShaderType, qualifier) &&
+ !IsTessellationControlShaderInput(mShaderType, qualifier) &&
+ !IsTessellationEvaluationShaderInput(mShaderType, qualifier))
+ {
+ return;
+ }
+
+ // Such variables must be declared as arrays or inside output blocks declared as arrays.
+ if (!type->isArray())
+ {
+ error(location, "Tessellation interface variables must be declared as an array", token);
+ return;
+ }
+
+ // If a size is specified, it must match the maximum patch size.
+ unsigned int outermostSize = type->getOutermostArraySize();
+ if (outermostSize == 0u)
+ {
+ switch (qualifier)
+ {
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ case EvqFlatIn:
+ case EvqCentroidIn:
+ case EvqSmoothIn:
+ case EvqSampleIn:
+ // Declaring an array size is optional. If no size is specified, it will be taken
+ // from the implementation-dependent maximum patch size (gl_MaxPatchVertices).
+ ASSERT(mMaxPatchVertices > 0);
+ type->sizeOutermostUnsizedArray(mMaxPatchVertices);
+ break;
+ case EvqTessControlOut:
+ case EvqFlatOut:
+ case EvqCentroidOut:
+ case EvqSmoothOut:
+ case EvqSampleOut:
+ // Declaring an array size is optional. If no size is specified, it will be taken
+ // from output patch size declared in the shader. If the patch size is not yet
+ // declared, this is deferred until such time as it does.
+ if (mTessControlShaderOutputVertices == 0)
+ {
+ mDeferredArrayTypesToSize.push_back(type);
+ }
+ else
+ {
+ type->sizeOutermostUnsizedArray(mTessControlShaderOutputVertices);
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return;
+ }
+
+ if (IsTessellationControlShaderInput(mShaderType, qualifier) ||
+ IsTessellationEvaluationShaderInput(mShaderType, qualifier))
+ {
+ if (outermostSize != static_cast<unsigned int>(mMaxPatchVertices))
+ {
+ error(location,
+ "If a size is specified for a tessellation control or evaluation user-defined "
+ "input variable, it must match the maximum patch size (gl_MaxPatchVertices).",
+ token);
+ }
+ }
+ else if (IsTessellationControlShaderOutput(mShaderType, qualifier))
+ {
+ if (outermostSize != static_cast<unsigned int>(mTessControlShaderOutputVertices) &&
+ mTessControlShaderOutputVertices != 0)
+ {
+ error(location,
+ "If a size is specified for a tessellation control user-defined per-vertex "
+ "output variable, it must match the the number of vertices in the output "
+ "patch.",
+ token);
+ }
+ }
+}
+
+TIntermDeclaration *TParseContext::parseSingleDeclaration(
+ TPublicType &publicType,
+ const TSourceLoc &identifierOrTypeLocation,
+ const ImmutableString &identifier)
+{
+ TType *type = new TType(publicType);
+ if (mCompileOptions.flattenPragmaSTDGLInvariantAll &&
+ mDirectiveHandler.pragma().stdgl.invariantAll)
+ {
+ TQualifier qualifier = type->getQualifier();
+
+ // The directive handler has already taken care of rejecting invalid uses of this pragma
+ // (for example, in ESSL 3.00 fragment shaders), so at this point, flatten it into all
+ // affected variable declarations:
+ //
+ // 1. Built-in special variables which are inputs to the fragment shader. (These are handled
+ // elsewhere, in TranslatorGLSL.)
+ //
+ // 2. Outputs from vertex shaders in ESSL 1.00 and 3.00 (EvqVaryingOut and EvqVertexOut). It
+ // is actually less likely that there will be bugs in the handling of ESSL 3.00 shaders, but
+ // the way this is currently implemented we have to enable this compiler option before
+ // parsing the shader and determining the shading language version it uses. If this were
+ // implemented as a post-pass, the workaround could be more targeted.
+ if (qualifier == EvqVaryingOut || qualifier == EvqVertexOut)
+ {
+ type->setInvariant(true);
+ }
+ }
+
+ checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier, type);
+ checkTessellationShaderUnsizedArraysAndSetSize(identifierOrTypeLocation, identifier, type);
+
+ declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
+ identifierOrTypeLocation);
+
+ bool emptyDeclaration = (identifier == "");
+ mDeferredNonEmptyDeclarationErrorCheck = emptyDeclaration;
+
+ TIntermSymbol *symbol = nullptr;
+ if (emptyDeclaration)
+ {
+ emptyDeclarationErrorCheck(*type, identifierOrTypeLocation);
+ // In most cases we don't need to create a symbol node for an empty declaration.
+ // But if the empty declaration is declaring a struct type, the symbol node will store that.
+ if (type->getBasicType() == EbtStruct)
+ {
+ TVariable *emptyVariable =
+ new TVariable(&symbolTable, kEmptyImmutableString, type, SymbolType::Empty);
+ symbol = new TIntermSymbol(emptyVariable);
+ }
+ else if (IsAtomicCounter(publicType.getBasicType()))
+ {
+ setAtomicCounterBindingDefaultOffset(publicType, identifierOrTypeLocation);
+ }
+ }
+ else
+ {
+ nonEmptyDeclarationErrorCheck(publicType, identifierOrTypeLocation);
+
+ checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, type);
+
+ if (IsAtomicCounter(type->getBasicType()))
+ {
+ checkAtomicCounterOffsetDoesNotOverlap(false, identifierOrTypeLocation, type);
+
+ checkAtomicCounterOffsetAlignment(identifierOrTypeLocation, *type);
+ }
+
+ TVariable *variable = nullptr;
+ if (declareVariable(identifierOrTypeLocation, identifier, type, &variable))
+ {
+ symbol = new TIntermSymbol(variable);
+ }
+ }
+
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierOrTypeLocation);
+ if (symbol)
+ {
+ symbol->setLine(identifierOrTypeLocation);
+ declaration->appendDeclarator(symbol);
+ }
+ return declaration;
+}
+
+TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(
+ TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes)
+{
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+
+ declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier,
+ identifierLocation);
+
+ nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
+
+ checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
+
+ TType *arrayType = new TType(elementType);
+ arrayType->makeArrays(arraySizes);
+
+ checkArrayOfArraysInOut(indexLocation, elementType, *arrayType);
+
+ checkGeometryShaderInputAndSetArraySize(indexLocation, identifier, arrayType);
+ checkTessellationShaderUnsizedArraysAndSetSize(indexLocation, identifier, arrayType);
+
+ checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
+
+ if (IsAtomicCounter(arrayType->getBasicType()))
+ {
+ checkAtomicCounterOffsetDoesNotOverlap(false, identifierLocation, arrayType);
+
+ checkAtomicCounterOffsetAlignment(identifierLocation, *arrayType);
+ }
+
+ adjustRedeclaredBuiltInType(identifier, arrayType);
+
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierLocation);
+
+ TVariable *variable = nullptr;
+ if (declareVariable(identifierLocation, identifier, arrayType, &variable))
+ {
+ TIntermSymbol *symbol = new TIntermSymbol(variable);
+ symbol->setLine(identifierLocation);
+ declaration->appendDeclarator(symbol);
+ }
+
+ return declaration;
+}
+
+TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer)
+{
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+
+ declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
+ identifierLocation);
+
+ nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
+
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierLocation);
+
+ TIntermBinary *initNode = nullptr;
+ TType *type = new TType(publicType);
+ if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
+ {
+ if (initNode)
+ {
+ declaration->appendDeclarator(initNode);
+ }
+ else if (publicType.isStructSpecifier())
+ {
+ // The initialization got constant folded. If it's a struct, declare the struct anyway.
+ TVariable *emptyVariable =
+ new TVariable(&symbolTable, kEmptyImmutableString, type, SymbolType::Empty);
+ TIntermSymbol *symbol = new TIntermSymbol(emptyVariable);
+ symbol->setLine(publicType.getLine());
+ declaration->appendDeclarator(symbol);
+ }
+ }
+ return declaration;
+}
+
+TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
+ TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer)
+{
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+
+ declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier,
+ identifierLocation);
+
+ nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
+
+ checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
+
+ TType *arrayType = new TType(elementType);
+ arrayType->makeArrays(arraySizes);
+
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierLocation);
+
+ // initNode will correspond to the whole of "type b[n] = initializer".
+ TIntermBinary *initNode = nullptr;
+ if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
+ {
+ if (initNode)
+ {
+ declaration->appendDeclarator(initNode);
+ }
+ }
+
+ return declaration;
+}
+
+TIntermGlobalQualifierDeclaration *TParseContext::parseGlobalQualifierDeclaration(
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TSourceLoc &identifierLoc,
+ const ImmutableString &identifier,
+ const TSymbol *symbol)
+{
+ TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
+
+ if (!typeQualifier.invariant && !typeQualifier.precise)
+ {
+ error(identifierLoc, "Expected invariant or precise", identifier);
+ return nullptr;
+ }
+ if (typeQualifier.invariant && !checkIsAtGlobalLevel(identifierLoc, "invariant varying"))
+ {
+ return nullptr;
+ }
+ if (!symbol)
+ {
+ error(identifierLoc, "undeclared identifier declared as invariant or precise", identifier);
+ return nullptr;
+ }
+ if (!IsQualifierUnspecified(typeQualifier.qualifier))
+ {
+ error(identifierLoc, "invariant or precise declaration specifies qualifier",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ if (typeQualifier.precision != EbpUndefined)
+ {
+ error(identifierLoc, "invariant or precise declaration specifies precision",
+ getPrecisionString(typeQualifier.precision));
+ }
+ if (!typeQualifier.layoutQualifier.isEmpty())
+ {
+ error(identifierLoc, "invariant or precise declaration specifies layout", "'layout'");
+ }
+
+ const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
+ if (!variable)
+ {
+ return nullptr;
+ }
+ const TType &type = variable->getType();
+
+ checkInvariantVariableQualifier(typeQualifier.invariant, type.getQualifier(),
+ typeQualifier.line);
+ checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
+
+ symbolTable.addInvariantVarying(*variable);
+
+ TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
+ intermSymbol->setLine(identifierLoc);
+
+ return new TIntermGlobalQualifierDeclaration(intermSymbol, typeQualifier.precise,
+ identifierLoc);
+}
+
+void TParseContext::parseDeclarator(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ TIntermDeclaration *declarationOut)
+{
+ // If the declaration starting this declarator list was empty (example: int,), some checks were
+ // not performed.
+ if (mDeferredNonEmptyDeclarationErrorCheck)
+ {
+ nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+ }
+
+ checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
+
+ TType *type = new TType(publicType);
+
+ checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier, type);
+ checkTessellationShaderUnsizedArraysAndSetSize(identifierLocation, identifier, type);
+
+ checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, type);
+
+ if (IsAtomicCounter(type->getBasicType()))
+ {
+ checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, type);
+
+ checkAtomicCounterOffsetAlignment(identifierLocation, *type);
+ }
+
+ adjustRedeclaredBuiltInType(identifier, type);
+
+ TVariable *variable = nullptr;
+ if (declareVariable(identifierLocation, identifier, type, &variable))
+ {
+ TIntermSymbol *symbol = new TIntermSymbol(variable);
+ symbol->setLine(identifierLocation);
+ declarationOut->appendDeclarator(symbol);
+ }
+}
+
+void TParseContext::parseArrayDeclarator(TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &arrayLocation,
+ const TVector<unsigned int> &arraySizes,
+ TIntermDeclaration *declarationOut)
+{
+ // If the declaration starting this declarator list was empty (example: int,), some checks were
+ // not performed.
+ if (mDeferredNonEmptyDeclarationErrorCheck)
+ {
+ nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+ }
+
+ checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType);
+
+ if (checkIsValidTypeAndQualifierForArray(arrayLocation, elementType))
+ {
+ TType *arrayType = new TType(elementType);
+ arrayType->makeArrays(arraySizes);
+
+ checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier, arrayType);
+ checkTessellationShaderUnsizedArraysAndSetSize(identifierLocation, identifier, arrayType);
+
+ checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
+
+ if (IsAtomicCounter(arrayType->getBasicType()))
+ {
+ checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, arrayType);
+
+ checkAtomicCounterOffsetAlignment(identifierLocation, *arrayType);
+ }
+
+ adjustRedeclaredBuiltInType(identifier, arrayType);
+
+ TVariable *variable = nullptr;
+ if (declareVariable(identifierLocation, identifier, arrayType, &variable))
+ {
+ TIntermSymbol *symbol = new TIntermSymbol(variable);
+ symbol->setLine(identifierLocation);
+ declarationOut->appendDeclarator(symbol);
+ }
+ }
+}
+
+void TParseContext::parseInitDeclarator(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut)
+{
+ // If the declaration starting this declarator list was empty (example: int,), some checks were
+ // not performed.
+ if (mDeferredNonEmptyDeclarationErrorCheck)
+ {
+ nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+ }
+
+ checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
+
+ TIntermBinary *initNode = nullptr;
+ TType *type = new TType(publicType);
+ if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
+ {
+ //
+ // build the intermediate representation
+ //
+ if (initNode)
+ {
+ declarationOut->appendDeclarator(initNode);
+ }
+ }
+}
+
+void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut)
+{
+ // If the declaration starting this declarator list was empty (example: int,), some checks were
+ // not performed.
+ if (mDeferredNonEmptyDeclarationErrorCheck)
+ {
+ nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+ }
+
+ checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType);
+
+ checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
+
+ TType *arrayType = new TType(elementType);
+ arrayType->makeArrays(arraySizes);
+
+ // initNode will correspond to the whole of "b[n] = initializer".
+ TIntermBinary *initNode = nullptr;
+ if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
+ {
+ if (initNode)
+ {
+ declarationOut->appendDeclarator(initNode);
+ }
+ }
+}
+
+TIntermNode *TParseContext::addEmptyStatement(const TSourceLoc &location)
+{
+ // It's simpler to parse an empty statement as a constant expression rather than having a
+ // different type of node just for empty statements, that will be pruned from the AST anyway.
+ TIntermNode *node = CreateZeroNode(TType(EbtInt, EbpMedium));
+ node->setLine(location);
+ return node;
+}
+
+void TParseContext::setAtomicCounterBindingDefaultOffset(const TPublicType &publicType,
+ const TSourceLoc &location)
+{
+ const TLayoutQualifier &layoutQualifier = publicType.layoutQualifier;
+ checkAtomicCounterBindingIsValid(location, layoutQualifier.binding);
+ if (layoutQualifier.binding == -1 || layoutQualifier.offset == -1)
+ {
+ error(location, "Requires both binding and offset", "layout");
+ return;
+ }
+ mAtomicCounterBindingStates[layoutQualifier.binding].setDefaultOffset(layoutQualifier.offset);
+}
+
+void TParseContext::parseDefaultPrecisionQualifier(const TPrecision precision,
+ const TPublicType &type,
+ const TSourceLoc &loc)
+{
+ if ((precision == EbpHigh) && (getShaderType() == GL_FRAGMENT_SHADER) &&
+ !getFragmentPrecisionHigh())
+ {
+ error(loc, "precision is not supported in fragment shader", "highp");
+ }
+
+ if (!CanSetDefaultPrecisionOnType(type))
+ {
+ error(loc, "illegal type argument for default precision qualifier",
+ getBasicString(type.getBasicType()));
+ return;
+ }
+ symbolTable.setDefaultPrecision(type.getBasicType(), precision);
+}
+
+bool TParseContext::checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier)
+{
+ switch (typeQualifier.layoutQualifier.primitiveType)
+ {
+ case EptLines:
+ case EptLinesAdjacency:
+ case EptTriangles:
+ case EptTrianglesAdjacency:
+ return typeQualifier.qualifier == EvqGeometryIn;
+
+ case EptLineStrip:
+ case EptTriangleStrip:
+ return typeQualifier.qualifier == EvqGeometryOut;
+
+ case EptPoints:
+ return true;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize,
+ const TSourceLoc &line)
+{
+ if (!symbolTable.setGlInArraySize(inputArraySize))
+ {
+ error(line,
+ "Array size or input primitive declaration doesn't match the size of earlier sized "
+ "array inputs.",
+ "layout");
+ }
+ mGeometryInputArraySize = inputArraySize;
+}
+
+bool TParseContext::parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier)
+{
+ ASSERT(typeQualifier.qualifier == EvqGeometryIn);
+
+ const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
+
+ if (layoutQualifier.maxVertices != -1)
+ {
+ error(typeQualifier.line,
+ "max_vertices can only be declared in 'out' layout in a geometry shader", "layout");
+ return false;
+ }
+
+ // Set mGeometryInputPrimitiveType if exists
+ if (layoutQualifier.primitiveType != EptUndefined)
+ {
+ if (!checkPrimitiveTypeMatchesTypeQualifier(typeQualifier))
+ {
+ error(typeQualifier.line, "invalid primitive type for 'in' layout", "layout");
+ return false;
+ }
+
+ if (mGeometryShaderInputPrimitiveType == EptUndefined)
+ {
+ mGeometryShaderInputPrimitiveType = layoutQualifier.primitiveType;
+ setGeometryShaderInputArraySize(
+ GetGeometryShaderInputArraySize(mGeometryShaderInputPrimitiveType),
+ typeQualifier.line);
+ }
+ else if (mGeometryShaderInputPrimitiveType != layoutQualifier.primitiveType)
+ {
+ error(typeQualifier.line, "primitive doesn't match earlier input primitive declaration",
+ "layout");
+ return false;
+ }
+
+ // Size any implicitly sized arrays that have already been declared.
+ for (TType *type : mDeferredArrayTypesToSize)
+ {
+ type->sizeOutermostUnsizedArray(
+ symbolTable.getGlInVariableWithArraySize()->getType().getOutermostArraySize());
+ }
+ mDeferredArrayTypesToSize.clear();
+ }
+
+ // Set mGeometryInvocations if exists
+ if (layoutQualifier.invocations > 0)
+ {
+ if (mGeometryShaderInvocations == 0)
+ {
+ mGeometryShaderInvocations = layoutQualifier.invocations;
+ }
+ else if (mGeometryShaderInvocations != layoutQualifier.invocations)
+ {
+ error(typeQualifier.line, "invocations contradicts to the earlier declaration",
+ "layout");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool TParseContext::parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier)
+{
+ ASSERT(typeQualifier.qualifier == EvqGeometryOut);
+
+ const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
+
+ if (layoutQualifier.invocations > 0)
+ {
+ error(typeQualifier.line,
+ "invocations can only be declared in 'in' layout in a geometry shader", "layout");
+ return false;
+ }
+
+ // Set mGeometryOutputPrimitiveType if exists
+ if (layoutQualifier.primitiveType != EptUndefined)
+ {
+ if (!checkPrimitiveTypeMatchesTypeQualifier(typeQualifier))
+ {
+ error(typeQualifier.line, "invalid primitive type for 'out' layout", "layout");
+ return false;
+ }
+
+ if (mGeometryShaderOutputPrimitiveType == EptUndefined)
+ {
+ mGeometryShaderOutputPrimitiveType = layoutQualifier.primitiveType;
+ }
+ else if (mGeometryShaderOutputPrimitiveType != layoutQualifier.primitiveType)
+ {
+ error(typeQualifier.line,
+ "primitive doesn't match earlier output primitive declaration", "layout");
+ return false;
+ }
+ }
+
+ // Set mGeometryMaxVertices if exists
+ if (layoutQualifier.maxVertices > -1)
+ {
+ if (mGeometryShaderMaxVertices == -1)
+ {
+ mGeometryShaderMaxVertices = layoutQualifier.maxVertices;
+ }
+ else if (mGeometryShaderMaxVertices != layoutQualifier.maxVertices)
+ {
+ error(typeQualifier.line, "max_vertices contradicts to the earlier declaration",
+ "layout");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool TParseContext::parseTessControlShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier)
+{
+ ASSERT(typeQualifier.qualifier == EvqTessControlOut);
+
+ const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
+
+ if (layoutQualifier.vertices == 0)
+ {
+ error(typeQualifier.line, "No vertices specified", "layout");
+ return false;
+ }
+
+ // Set mTessControlShaderOutputVertices if exists
+ if (mTessControlShaderOutputVertices == 0)
+ {
+ mTessControlShaderOutputVertices = layoutQualifier.vertices;
+
+ // Size any implicitly sized arrays that have already been declared.
+ for (TType *type : mDeferredArrayTypesToSize)
+ {
+ type->sizeOutermostUnsizedArray(mTessControlShaderOutputVertices);
+ }
+ mDeferredArrayTypesToSize.clear();
+ }
+ else
+ {
+ error(typeQualifier.line, "Duplicated vertices specified", "layout");
+ }
+ return true;
+}
+
+bool TParseContext::parseTessEvaluationShaderInputLayoutQualifier(
+ const TTypeQualifier &typeQualifier)
+{
+ ASSERT(typeQualifier.qualifier == EvqTessEvaluationIn);
+
+ const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
+
+ // Set mTessEvaluationShaderInputPrimitiveType if exists
+ if (layoutQualifier.tesPrimitiveType != EtetUndefined)
+ {
+ if (mTessEvaluationShaderInputPrimitiveType == EtetUndefined)
+ {
+ mTessEvaluationShaderInputPrimitiveType = layoutQualifier.tesPrimitiveType;
+ }
+ else
+ {
+ error(typeQualifier.line, "Duplicated primitive type declaration", "layout");
+ }
+ }
+ // Set mTessEvaluationShaderVertexSpacingType if exists
+ if (layoutQualifier.tesVertexSpacingType != EtetUndefined)
+ {
+ if (mTessEvaluationShaderInputVertexSpacingType == EtetUndefined)
+ {
+ mTessEvaluationShaderInputVertexSpacingType = layoutQualifier.tesVertexSpacingType;
+ }
+ else
+ {
+ error(typeQualifier.line, "Duplicated vertex spacing declaration", "layout");
+ }
+ }
+ // Set mTessEvaluationShaderInputOrderingType if exists
+ if (layoutQualifier.tesOrderingType != EtetUndefined)
+ {
+ if (mTessEvaluationShaderInputOrderingType == EtetUndefined)
+ {
+ mTessEvaluationShaderInputOrderingType = layoutQualifier.tesOrderingType;
+ }
+ else
+ {
+ error(typeQualifier.line, "Duplicated ordering declaration", "layout");
+ }
+ }
+ // Set mTessEvaluationShaderInputPointType if exists
+ if (layoutQualifier.tesPointType != EtetUndefined)
+ {
+ if (mTessEvaluationShaderInputPointType == EtetUndefined)
+ {
+ mTessEvaluationShaderInputPointType = layoutQualifier.tesPointType;
+ }
+ else
+ {
+ error(typeQualifier.line, "Duplicated point type declaration", "layout");
+ }
+ }
+
+ return true;
+}
+
+void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder)
+{
+ TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
+ const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
+
+ checkInvariantVariableQualifier(typeQualifier.invariant, typeQualifier.qualifier,
+ typeQualifier.line);
+
+ // It should never be the case, but some strange parser errors can send us here.
+ if (layoutQualifier.isEmpty())
+ {
+ error(typeQualifier.line, "Error during layout qualifier parsing.", "?");
+ return;
+ }
+
+ if (!layoutQualifier.isCombinationValid())
+ {
+ error(typeQualifier.line, "invalid layout qualifier combination", "layout");
+ return;
+ }
+
+ checkIndexIsNotSpecified(typeQualifier.line, layoutQualifier.index);
+
+ checkBindingIsNotSpecified(typeQualifier.line, layoutQualifier.binding);
+
+ checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
+
+ checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat);
+
+ checkYuvIsNotSpecified(typeQualifier.line, layoutQualifier.yuv);
+
+ checkOffsetIsNotSpecified(typeQualifier.line, layoutQualifier.offset);
+
+ checkStd430IsForShaderStorageBlock(typeQualifier.line, layoutQualifier.blockStorage,
+ typeQualifier.qualifier);
+
+ checkAdvancedBlendEquationsNotSpecified(
+ typeQualifier.line, layoutQualifier.advancedBlendEquations, typeQualifier.qualifier);
+
+ if (typeQualifier.qualifier != EvqFragmentIn)
+ {
+ checkEarlyFragmentTestsIsNotSpecified(typeQualifier.line,
+ layoutQualifier.earlyFragmentTests);
+ }
+
+ if (typeQualifier.qualifier == EvqComputeIn)
+ {
+ if (mComputeShaderLocalSizeDeclared &&
+ !layoutQualifier.isLocalSizeEqual(mComputeShaderLocalSize))
+ {
+ error(typeQualifier.line, "Work group size does not match the previous declaration",
+ "layout");
+ return;
+ }
+
+ if (mShaderVersion < 310)
+ {
+ error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout");
+ return;
+ }
+
+ if (!layoutQualifier.localSize.isAnyValueSet())
+ {
+ error(typeQualifier.line, "No local work group size specified", "layout");
+ return;
+ }
+
+ const TVariable *maxComputeWorkGroupSize = static_cast<const TVariable *>(
+ symbolTable.findBuiltIn(ImmutableString("gl_MaxComputeWorkGroupSize"), mShaderVersion));
+
+ const TConstantUnion *maxComputeWorkGroupSizeData =
+ maxComputeWorkGroupSize->getConstPointer();
+
+ for (size_t i = 0u; i < layoutQualifier.localSize.size(); ++i)
+ {
+ if (layoutQualifier.localSize[i] != -1)
+ {
+ mComputeShaderLocalSize[i] = layoutQualifier.localSize[i];
+ const int maxComputeWorkGroupSizeValue = maxComputeWorkGroupSizeData[i].getIConst();
+ if (mComputeShaderLocalSize[i] < 1 ||
+ mComputeShaderLocalSize[i] > maxComputeWorkGroupSizeValue)
+ {
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
+ reasonStream << "invalid value: Value must be at least 1 and no greater than "
+ << maxComputeWorkGroupSizeValue;
+ const std::string &reason = reasonStream.str();
+
+ error(typeQualifier.line, reason.c_str(), getWorkGroupSizeString(i));
+ return;
+ }
+ }
+ }
+
+ mComputeShaderLocalSizeDeclared = true;
+ }
+ else if (typeQualifier.qualifier == EvqGeometryIn)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout");
+ return;
+ }
+
+ if (!parseGeometryShaderInputLayoutQualifier(typeQualifier))
+ {
+ return;
+ }
+ }
+ else if (typeQualifier.qualifier == EvqGeometryOut)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(typeQualifier.line, "out type qualifier supported in GLSL ES 3.10 only",
+ "layout");
+ return;
+ }
+
+ if (!parseGeometryShaderOutputLayoutQualifier(typeQualifier))
+ {
+ return;
+ }
+ }
+ else if (anyMultiviewExtensionAvailable() && typeQualifier.qualifier == EvqVertexIn)
+ {
+ // This error is only specified in WebGL, but tightens unspecified behavior in the native
+ // specification.
+ if (mNumViews != -1 && layoutQualifier.numViews != mNumViews)
+ {
+ error(typeQualifier.line, "Number of views does not match the previous declaration",
+ "layout");
+ return;
+ }
+
+ if (layoutQualifier.numViews == -1)
+ {
+ error(typeQualifier.line, "No num_views specified", "layout");
+ return;
+ }
+
+ if (layoutQualifier.numViews > mMaxNumViews)
+ {
+ error(typeQualifier.line, "num_views greater than the value of GL_MAX_VIEWS_OVR",
+ "layout");
+ return;
+ }
+
+ mNumViews = layoutQualifier.numViews;
+ }
+ else if (typeQualifier.qualifier == EvqFragmentIn)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(typeQualifier.line,
+ "in type qualifier without variable declaration supported in GLSL ES 3.10 and "
+ "after",
+ "layout");
+ return;
+ }
+
+ if (!layoutQualifier.earlyFragmentTests)
+ {
+ error(typeQualifier.line,
+ "only early_fragment_tests is allowed as layout qualifier when not declaring a "
+ "variable",
+ "layout");
+ return;
+ }
+
+ mEarlyFragmentTestsSpecified = true;
+ }
+ else if (typeQualifier.qualifier == EvqFragmentOut)
+ {
+ if (mShaderVersion < 320 && !isExtensionEnabled(TExtension::KHR_blend_equation_advanced))
+ {
+ error(typeQualifier.line,
+ "out type qualifier without variable declaration is supported in GLSL ES 3.20,"
+ " or if GL_KHR_blend_equation_advanced is enabled",
+ "layout");
+ return;
+ }
+
+ if (!layoutQualifier.advancedBlendEquations.any())
+ {
+ error(typeQualifier.line,
+ "only blend equations are allowed as layout qualifier when not declaring a "
+ "variable",
+ "layout");
+ return;
+ }
+
+ mAdvancedBlendEquations |= layoutQualifier.advancedBlendEquations;
+ }
+ else if (typeQualifier.qualifier == EvqTessControlOut)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(typeQualifier.line, "out type qualifier supported in GLSL ES 3.10 and after",
+ "layout");
+ return;
+ }
+
+ if (!parseTessControlShaderOutputLayoutQualifier(typeQualifier))
+ {
+ return;
+ }
+ }
+ else if (typeQualifier.qualifier == EvqTessEvaluationIn)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 and after",
+ "layout");
+ return;
+ }
+
+ if (!parseTessEvaluationShaderInputLayoutQualifier(typeQualifier))
+ {
+ return;
+ }
+ }
+ else
+ {
+ if (!checkWorkGroupSizeIsNotSpecified(typeQualifier.line, layoutQualifier))
+ {
+ return;
+ }
+
+ if (typeQualifier.qualifier != EvqUniform && typeQualifier.qualifier != EvqBuffer)
+ {
+ error(typeQualifier.line, "invalid qualifier: global layout can only be set for blocks",
+ getQualifierString(typeQualifier.qualifier));
+ return;
+ }
+
+ if (mShaderVersion < 300)
+ {
+ error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 and after",
+ "layout");
+ return;
+ }
+
+ checkLocationIsNotSpecified(typeQualifier.line, layoutQualifier);
+
+ if (layoutQualifier.matrixPacking != EmpUnspecified)
+ {
+ if (typeQualifier.qualifier == EvqUniform)
+ {
+ mDefaultUniformMatrixPacking = layoutQualifier.matrixPacking;
+ }
+ else if (typeQualifier.qualifier == EvqBuffer)
+ {
+ mDefaultBufferMatrixPacking = layoutQualifier.matrixPacking;
+ }
+ }
+
+ if (layoutQualifier.blockStorage != EbsUnspecified)
+ {
+ if (typeQualifier.qualifier == EvqUniform)
+ {
+ mDefaultUniformBlockStorage = layoutQualifier.blockStorage;
+ }
+ else if (typeQualifier.qualifier == EvqBuffer)
+ {
+ mDefaultBufferBlockStorage = layoutQualifier.blockStorage;
+ }
+ }
+ }
+}
+
+TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
+ const TFunction &function,
+ const TSourceLoc &location,
+ bool insertParametersToSymbolTable)
+{
+ checkIsNotReserved(location, function.name());
+
+ TIntermFunctionPrototype *prototype = new TIntermFunctionPrototype(&function);
+ prototype->setLine(location);
+
+ for (size_t i = 0; i < function.getParamCount(); i++)
+ {
+ const TVariable *param = function.getParam(i);
+
+ // If the parameter has no name, it's not an error, just don't add it to symbol table (could
+ // be used for unused args).
+ if (param->symbolType() != SymbolType::Empty)
+ {
+ if (insertParametersToSymbolTable)
+ {
+ if (!symbolTable.declare(const_cast<TVariable *>(param)))
+ {
+ error(location, "redefinition", param->name());
+ }
+ }
+ // Unsized type of a named parameter should have already been checked and sanitized.
+ ASSERT(!param->getType().isUnsizedArray());
+ }
+ else
+ {
+ if (param->getType().isUnsizedArray())
+ {
+ error(location, "function parameter array must be sized at compile time", "[]");
+ // We don't need to size the arrays since the parameter is unnamed and hence
+ // inaccessible.
+ }
+ }
+ }
+ return prototype;
+}
+
+TIntermFunctionPrototype *TParseContext::addFunctionPrototypeDeclaration(
+ const TFunction &parsedFunction,
+ const TSourceLoc &location)
+{
+ // Note: function found from the symbol table could be the same as parsedFunction if this is the
+ // first declaration. Either way the instance in the symbol table is used to track whether the
+ // function is declared multiple times.
+ bool hadPrototypeDeclaration = false;
+ const TFunction *function = symbolTable.markFunctionHasPrototypeDeclaration(
+ parsedFunction.getMangledName(), &hadPrototypeDeclaration);
+
+ if (hadPrototypeDeclaration && mShaderVersion == 100)
+ {
+ // ESSL 1.00.17 section 4.2.7.
+ // Doesn't apply to ESSL 3.00.4: see section 4.2.3.
+ error(location, "duplicate function prototype declarations are not allowed", "function");
+ }
+
+ TIntermFunctionPrototype *prototype =
+ createPrototypeNodeFromFunction(*function, location, false);
+
+ symbolTable.pop();
+
+ if (!symbolTable.atGlobalLevel())
+ {
+ // ESSL 3.00.4 section 4.2.4.
+ error(location, "local function prototype declarations are not allowed", "function");
+ }
+
+ return prototype;
+}
+
+TIntermFunctionDefinition *TParseContext::addFunctionDefinition(
+ TIntermFunctionPrototype *functionPrototype,
+ TIntermBlock *functionBody,
+ const TSourceLoc &location)
+{
+ // Undo push at end of parseFunctionDefinitionHeader() below for ESSL1.00 case
+ if (mFunctionBodyNewScope)
+ {
+ mFunctionBodyNewScope = false;
+ symbolTable.pop();
+ }
+
+ // Check that non-void functions have at least one return statement.
+ if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
+ {
+ error(location,
+ "function does not return a value:", functionPrototype->getFunction()->name());
+ }
+
+ if (functionBody == nullptr)
+ {
+ functionBody = new TIntermBlock();
+ functionBody->setLine(location);
+ }
+ TIntermFunctionDefinition *functionNode =
+ new TIntermFunctionDefinition(functionPrototype, functionBody);
+ functionNode->setLine(location);
+
+ symbolTable.pop();
+ return functionNode;
+}
+
+void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location,
+ const TFunction *function,
+ TIntermFunctionPrototype **prototypeOut)
+{
+ ASSERT(function);
+
+ bool wasDefined = false;
+ function = symbolTable.setFunctionParameterNamesFromDefinition(function, &wasDefined);
+ if (wasDefined)
+ {
+ error(location, "function already has a body", function->name());
+ }
+
+ // Remember the return type for later checking for return statements.
+ mCurrentFunctionType = &(function->getReturnType());
+ mFunctionReturnsValue = false;
+
+ *prototypeOut = createPrototypeNodeFromFunction(*function, location, true);
+ setLoopNestingLevel(0);
+
+ // ESSL 1.00 spec allows for variable in function body to redefine parameter
+ if (IsSpecWithFunctionBodyNewScope(mShaderSpec, mShaderVersion))
+ {
+ mFunctionBodyNewScope = true;
+ symbolTable.push();
+ }
+}
+
+TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
+{
+ //
+ // We don't know at this point whether this is a function definition or a prototype.
+ // The definition production code will check for redefinitions.
+ // In the case of ESSL 1.00 the prototype production code will also check for redeclarations.
+ //
+
+ for (size_t i = 0u; i < function->getParamCount(); ++i)
+ {
+ const TVariable *param = function->getParam(i);
+ const TType &paramType = param->getType();
+
+ if (paramType.isStructSpecifier())
+ {
+ // ESSL 3.00.6 section 12.10.
+ error(location, "Function parameter type cannot be a structure definition",
+ function->name());
+ }
+
+ checkPrecisionSpecified(location, paramType.getPrecision(), paramType.getBasicType());
+ }
+
+ if (getShaderVersion() >= 300)
+ {
+ if (symbolTable.isUnmangledBuiltInName(function->name(), getShaderVersion(),
+ extensionBehavior()))
+ {
+ // With ESSL 3.00 and above, names of built-in functions cannot be redeclared as
+ // functions. Therefore overloading or redefining builtin functions is an error.
+ error(location, "Name of a built-in function cannot be redeclared as function",
+ function->name());
+ }
+ }
+ else
+ {
+ // ESSL 1.00.17 section 4.2.6: built-ins can be overloaded but not redefined. We assume that
+ // this applies to redeclarations as well.
+ const TSymbol *builtIn =
+ symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion());
+ if (builtIn)
+ {
+ error(location, "built-in functions cannot be redefined", function->name());
+ }
+ }
+
+ // Return types and parameter qualifiers must match in all redeclarations, so those are checked
+ // here.
+ const TFunction *prevDec =
+ static_cast<const TFunction *>(symbolTable.findGlobal(function->getMangledName()));
+ if (prevDec)
+ {
+ if (prevDec->getReturnType() != function->getReturnType())
+ {
+ error(location, "function must have the same return type in all of its declarations",
+ function->getReturnType().getBasicString());
+ }
+ for (size_t i = 0; i < prevDec->getParamCount(); ++i)
+ {
+ if (prevDec->getParam(i)->getType().getQualifier() !=
+ function->getParam(i)->getType().getQualifier())
+ {
+ error(location,
+ "function must have the same parameter qualifiers in all of its declarations",
+ function->getParam(i)->getType().getQualifierString());
+ }
+ }
+ }
+
+ // Check for previously declared variables using the same name.
+ const TSymbol *prevSym = symbolTable.find(function->name(), getShaderVersion());
+ bool insertUnmangledName = true;
+ if (prevSym)
+ {
+ if (!prevSym->isFunction())
+ {
+ error(location, "redefinition of a function", function->name());
+ }
+ insertUnmangledName = false;
+ }
+ // Parsing is at the inner scope level of the function's arguments and body statement at this
+ // point, but declareUserDefinedFunction takes care of declaring the function at the global
+ // scope.
+ symbolTable.declareUserDefinedFunction(function, insertUnmangledName);
+
+ // Raise error message if main function takes any parameters or return anything other than void
+ if (function->isMain())
+ {
+ if (function->getParamCount() > 0)
+ {
+ error(location, "function cannot take any parameter(s)", "main");
+ }
+ if (function->getReturnType().getBasicType() != EbtVoid)
+ {
+ error(location, "main function cannot return a value",
+ function->getReturnType().getBasicString());
+ }
+ }
+
+ mDeclaringMain = function->isMain();
+
+ //
+ // If this is a redeclaration, it could also be a definition, in which case, we want to use the
+ // variable names from this one, and not the one that's
+ // being redeclared. So, pass back up this declaration, not the one in the symbol table.
+ //
+ return function;
+}
+
+TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
+ const ImmutableString &name,
+ const TSourceLoc &location)
+{
+ if (type.qualifier != EvqGlobal && type.qualifier != EvqTemporary)
+ {
+ error(location, "no qualifiers allowed for function return",
+ getQualifierString(type.qualifier));
+ }
+ if (!type.layoutQualifier.isEmpty())
+ {
+ error(location, "no qualifiers allowed for function return", "layout");
+ }
+ // make sure an opaque type is not involved as well...
+ std::string reason(getBasicString(type.getBasicType()));
+ reason += "s can't be function return values";
+ checkIsNotOpaqueType(location, type.typeSpecifierNonArray, reason.c_str());
+ if (mShaderVersion < 300)
+ {
+ // Array return values are forbidden, but there's also no valid syntax for declaring array
+ // return values in ESSL 1.00.
+ ASSERT(!type.isArray() || mDiagnostics->numErrors() > 0);
+
+ if (type.isStructureContainingArrays())
+ {
+ // ESSL 1.00.17 section 6.1 Function Definitions
+ TInfoSinkBase typeString;
+ typeString << TType(type);
+ error(location, "structures containing arrays can't be function return values",
+ typeString.c_str());
+ }
+ }
+
+ // Add the function as a prototype after parsing it (we do not support recursion)
+ return new TFunction(&symbolTable, name, SymbolType::UserDefined, new TType(type), false);
+}
+
+TFunctionLookup *TParseContext::addNonConstructorFunc(const ImmutableString &name,
+ const TSymbol *symbol)
+{
+ return TFunctionLookup::CreateFunctionCall(name, symbol);
+}
+
+TFunctionLookup *TParseContext::addConstructorFunc(const TPublicType &publicType)
+{
+ if (mShaderVersion < 300 && publicType.isArray())
+ {
+ error(publicType.getLine(), "array constructor supported in GLSL ES 3.00 and above only",
+ "[]");
+ }
+ if (publicType.isStructSpecifier())
+ {
+ error(publicType.getLine(), "constructor can't be a structure definition",
+ getBasicString(publicType.getBasicType()));
+ }
+
+ TType *type = new TType(publicType);
+ if (!type->canBeConstructed())
+ {
+ error(publicType.getLine(), "cannot construct this type",
+ getBasicString(publicType.getBasicType()));
+ type->setBasicType(EbtFloat);
+ }
+ return TFunctionLookup::CreateConstructor(type);
+}
+
+void TParseContext::checkIsNotUnsizedArray(const TSourceLoc &line,
+ const char *errorMessage,
+ const ImmutableString &token,
+ TType *arrayType)
+{
+ if (arrayType->isUnsizedArray())
+ {
+ error(line, errorMessage, token);
+ arrayType->sizeUnsizedArrays(TSpan<const unsigned int>());
+ }
+}
+
+TParameter TParseContext::parseParameterDeclarator(TType *type,
+ const ImmutableString &name,
+ const TSourceLoc &nameLoc)
+{
+ ASSERT(type);
+ checkIsNotUnsizedArray(nameLoc, "function parameter array must specify a size", name, type);
+ if (type->getBasicType() == EbtVoid)
+ {
+ error(nameLoc, "illegal use of type 'void'", name);
+ }
+ checkIsNotReserved(nameLoc, name);
+ TParameter param = {name.data(), type};
+ return param;
+}
+
+TParameter TParseContext::parseParameterDeclarator(const TPublicType &publicType,
+ const ImmutableString &name,
+ const TSourceLoc &nameLoc)
+{
+ TType *type = new TType(publicType);
+ return parseParameterDeclarator(type, name, nameLoc);
+}
+
+TParameter TParseContext::parseParameterArrayDeclarator(const ImmutableString &name,
+ const TSourceLoc &nameLoc,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &arrayLoc,
+ TPublicType *elementType)
+{
+ checkArrayElementIsNotArray(arrayLoc, *elementType);
+ TType *arrayType = new TType(*elementType);
+ arrayType->makeArrays(arraySizes);
+ return parseParameterDeclarator(arrayType, name, nameLoc);
+}
+
+bool TParseContext::checkUnsizedArrayConstructorArgumentDimensionality(
+ const TIntermSequence &arguments,
+ TType type,
+ const TSourceLoc &line)
+{
+ if (arguments.empty())
+ {
+ error(line, "implicitly sized array constructor must have at least one argument", "[]");
+ return false;
+ }
+ for (TIntermNode *arg : arguments)
+ {
+ const TIntermTyped *element = arg->getAsTyped();
+ ASSERT(element);
+ size_t dimensionalityFromElement = element->getType().getNumArraySizes() + 1u;
+ if (dimensionalityFromElement > type.getNumArraySizes())
+ {
+ error(line, "constructing from a non-dereferenced array", "constructor");
+ return false;
+ }
+ else if (dimensionalityFromElement < type.getNumArraySizes())
+ {
+ if (dimensionalityFromElement == 1u)
+ {
+ error(line, "implicitly sized array of arrays constructor argument is not an array",
+ "constructor");
+ }
+ else
+ {
+ error(line,
+ "implicitly sized array of arrays constructor argument dimensionality is too "
+ "low",
+ "constructor");
+ }
+ return false;
+ }
+ }
+ return true;
+}
+
+// This function is used to test for the correctness of the parameters passed to various constructor
+// functions and also convert them to the right datatype if it is allowed and required.
+//
+// Returns a node to add to the tree regardless of if an error was generated or not.
+//
+TIntermTyped *TParseContext::addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line)
+{
+ TType type = fnCall->constructorType();
+ TIntermSequence &arguments = fnCall->arguments();
+ if (type.isUnsizedArray())
+ {
+ if (!checkUnsizedArrayConstructorArgumentDimensionality(arguments, type, line))
+ {
+ type.sizeUnsizedArrays(TSpan<const unsigned int>());
+ return CreateZeroNode(type);
+ }
+ TIntermTyped *firstElement = arguments.at(0)->getAsTyped();
+ ASSERT(firstElement);
+ if (type.getOutermostArraySize() == 0u)
+ {
+ type.sizeOutermostUnsizedArray(static_cast<unsigned int>(arguments.size()));
+ }
+ for (size_t i = 0; i < firstElement->getType().getNumArraySizes(); ++i)
+ {
+ if (type.getArraySizes()[i] == 0u)
+ {
+ type.setArraySize(i, firstElement->getType().getArraySizes()[i]);
+ }
+ }
+ ASSERT(!type.isUnsizedArray());
+ }
+
+ if (!checkConstructorArguments(line, arguments, type))
+ {
+ return CreateZeroNode(type);
+ }
+
+ TIntermAggregate *constructorNode = TIntermAggregate::CreateConstructor(type, &arguments);
+ constructorNode->setLine(line);
+
+ return constructorNode->fold(mDiagnostics);
+}
+
+//
+// Interface/uniform blocks
+TIntermDeclaration *TParseContext::addInterfaceBlock(
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TSourceLoc &nameLine,
+ const ImmutableString &blockName,
+ TFieldList *fieldList,
+ const ImmutableString &instanceName,
+ const TSourceLoc &instanceLine,
+ const TVector<unsigned int> *arraySizes,
+ const TSourceLoc &arraySizesLine)
+{
+ const bool isGLPerVertex = blockName == "gl_PerVertex";
+ // gl_PerVertex is allowed to be redefined and therefore not reserved
+ if (!isGLPerVertex)
+ {
+ checkIsNotReserved(nameLine, blockName);
+ }
+
+ TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
+
+ const bool isUniformOrBuffer =
+ typeQualifier.qualifier == EvqUniform || typeQualifier.qualifier == EvqBuffer;
+ const bool isShaderIoBlock = IsShaderIoBlock(typeQualifier.qualifier);
+
+ if (mShaderVersion < 310 && typeQualifier.qualifier != EvqUniform)
+ {
+ error(typeQualifier.line,
+ "invalid qualifier: interface blocks must be uniform in version lower than GLSL ES "
+ "3.10",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ else if (typeQualifier.qualifier == EvqPatchOut)
+ {
+ if ((!isExtensionEnabled(TExtension::EXT_tessellation_shader) && mShaderVersion < 320) ||
+ mShaderType != GL_TESS_CONTROL_SHADER)
+ {
+ error(typeQualifier.line,
+ "invalid qualifier: 'patch out' requires a tessellation control shader",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ }
+ else if (typeQualifier.qualifier == EvqPatchIn)
+ {
+ if ((!isExtensionEnabled(TExtension::EXT_tessellation_shader) && mShaderVersion < 320) ||
+ mShaderType != GL_TESS_EVALUATION_SHADER)
+ {
+ error(typeQualifier.line,
+ "invalid qualifier: 'patch in' requires a tessellation evaluation shader",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ }
+ else if (typeQualifier.qualifier != EvqUniform && typeQualifier.qualifier != EvqBuffer)
+ {
+ if (isShaderIoBlock)
+ {
+ if (!isExtensionEnabled(TExtension::OES_shader_io_blocks) &&
+ !isExtensionEnabled(TExtension::EXT_shader_io_blocks) &&
+ !isExtensionEnabled(TExtension::OES_geometry_shader) &&
+ !isExtensionEnabled(TExtension::EXT_geometry_shader) && mShaderVersion < 320)
+ {
+ error(typeQualifier.line,
+ "invalid qualifier: shader IO blocks need shader io block extension",
+ getQualifierString(typeQualifier.qualifier));
+ }
+
+ // Both inputs and outputs of tessellation control shaders must be arrays.
+ // For tessellation evaluation shaders, only inputs must necessarily be arrays.
+ const bool isTCS = mShaderType == GL_TESS_CONTROL_SHADER;
+ const bool isTESIn =
+ mShaderType == GL_TESS_EVALUATION_SHADER && IsShaderIn(typeQualifier.qualifier);
+ if (arraySizes == nullptr && (isTCS || isTESIn))
+ {
+ error(typeQualifier.line, "type must be an array", blockName);
+ }
+ }
+ else
+ {
+ error(typeQualifier.line,
+ "invalid qualifier: interface blocks must be uniform or buffer",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ }
+
+ if (typeQualifier.invariant)
+ {
+ error(typeQualifier.line, "invalid qualifier on interface block", "invariant");
+ }
+
+ if (typeQualifier.qualifier != EvqBuffer)
+ {
+ checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
+ }
+
+ // Verify array sizes
+ if (arraySizes)
+ {
+ if (isUniformOrBuffer)
+ {
+ if (arraySizes->size() == 0)
+ {
+ error(arraySizesLine, "unsized arrays are not allowed with interface blocks", "");
+ }
+ if (arraySizes->size() > 1)
+ {
+ error(arraySizesLine, "array of arrays are not allowed with interface blocks", "");
+ }
+ }
+ else if (isShaderIoBlock)
+ {
+ size_t arrayDimensions = arraySizes->size();
+
+ // Geometry shader inputs have a level arrayness that must be ignored.
+ if (mShaderType == GL_GEOMETRY_SHADER_EXT && IsVaryingIn(typeQualifier.qualifier))
+ {
+ ASSERT(arrayDimensions > 0);
+ --arrayDimensions;
+
+ // Validate that the array size of input matches the geometry layout
+ // declaration, if not automatic (specified as []).
+ const unsigned int geometryDim = arraySizes->back();
+ if (geometryDim > 0 && geometryDim != mGeometryInputArraySize)
+ {
+ error(arraySizesLine,
+ "geometry shader input block array size inconsistent "
+ "with primitive",
+ "");
+ }
+ }
+
+ if (arrayDimensions > 1)
+ {
+ error(arraySizesLine, "array of arrays are not allowed with I/O blocks", "");
+ }
+ }
+ }
+ else if (isShaderIoBlock && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+ IsVaryingIn(typeQualifier.qualifier))
+ {
+ error(arraySizesLine, "geometry shader input blocks must be an array", "");
+ }
+
+ checkIndexIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.index);
+
+ if (mShaderVersion < 310)
+ {
+ checkBindingIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.binding);
+ }
+ else
+ {
+ unsigned int arraySize =
+ arraySizes == nullptr || arraySizes->empty() ? 0 : (*arraySizes)[0];
+ checkBlockBindingIsValid(typeQualifier.line, typeQualifier.qualifier,
+ typeQualifier.layoutQualifier.binding, arraySize);
+ }
+
+ checkYuvIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.yuv);
+ checkEarlyFragmentTestsIsNotSpecified(typeQualifier.line,
+ typeQualifier.layoutQualifier.earlyFragmentTests);
+ checkNoncoherentIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.noncoherent);
+
+ TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
+ if (!IsShaderIoBlock(typeQualifier.qualifier) && typeQualifier.qualifier != EvqPatchIn &&
+ typeQualifier.qualifier != EvqPatchOut)
+ {
+ checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier);
+ }
+ checkStd430IsForShaderStorageBlock(typeQualifier.line, blockLayoutQualifier.blockStorage,
+ typeQualifier.qualifier);
+
+ if (blockLayoutQualifier.matrixPacking == EmpUnspecified)
+ {
+ if (typeQualifier.qualifier == EvqUniform)
+ {
+ blockLayoutQualifier.matrixPacking = mDefaultUniformMatrixPacking;
+ }
+ else if (typeQualifier.qualifier == EvqBuffer)
+ {
+ blockLayoutQualifier.matrixPacking = mDefaultBufferMatrixPacking;
+ }
+ }
+
+ if (blockLayoutQualifier.blockStorage == EbsUnspecified)
+ {
+ if (typeQualifier.qualifier == EvqUniform)
+ {
+ blockLayoutQualifier.blockStorage = mDefaultUniformBlockStorage;
+ }
+ else if (typeQualifier.qualifier == EvqBuffer)
+ {
+ blockLayoutQualifier.blockStorage = mDefaultBufferBlockStorage;
+ }
+ }
+
+ checkWorkGroupSizeIsNotSpecified(nameLine, blockLayoutQualifier);
+
+ checkInternalFormatIsNotSpecified(nameLine, blockLayoutQualifier.imageInternalFormat);
+
+ // check for sampler types and apply layout qualifiers
+ for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
+ {
+ TField *field = (*fieldList)[memberIndex];
+ TType *fieldType = field->type();
+ if (IsOpaqueType(fieldType->getBasicType()))
+ {
+ std::string reason("unsupported type - ");
+ reason += fieldType->getBasicString();
+ reason += " types are not allowed in interface blocks";
+ error(field->line(), reason.c_str(), fieldType->getBasicString());
+ }
+
+ const TQualifier qualifier = fieldType->getQualifier();
+ switch (qualifier)
+ {
+ case EvqGlobal:
+ break;
+ case EvqUniform:
+ if (typeQualifier.qualifier == EvqBuffer)
+ {
+ error(field->line(), "invalid qualifier on shader storage block member",
+ getQualifierString(qualifier));
+ }
+ break;
+ case EvqBuffer:
+ if (typeQualifier.qualifier == EvqUniform)
+ {
+ error(field->line(), "invalid qualifier on uniform block member",
+ getQualifierString(qualifier));
+ }
+ break;
+ // a member variable in io block may have different interpolation.
+ case EvqFlatIn:
+ case EvqFlatOut:
+ case EvqNoPerspectiveIn:
+ case EvqNoPerspectiveOut:
+ case EvqSmoothIn:
+ case EvqSmoothOut:
+ case EvqCentroidIn:
+ case EvqCentroidOut:
+ break;
+ // a member variable can have an incomplete qualifier because shader io block has either
+ // in or out.
+ case EvqSmooth:
+ case EvqFlat:
+ case EvqNoPerspective:
+ case EvqCentroid:
+ case EvqGeometryIn:
+ case EvqGeometryOut:
+ if (!IsShaderIoBlock(typeQualifier.qualifier) &&
+ typeQualifier.qualifier != EvqPatchIn &&
+ typeQualifier.qualifier != EvqPatchOut &&
+ typeQualifier.qualifier != EvqGeometryIn &&
+ typeQualifier.qualifier != EvqGeometryOut)
+ {
+ error(field->line(), "invalid qualifier on interface block member",
+ getQualifierString(qualifier));
+ }
+ break;
+ default:
+ error(field->line(), "invalid qualifier on interface block member",
+ getQualifierString(qualifier));
+ break;
+ }
+
+ // On interface block members, invariant is only applicable to output I/O blocks.
+ const bool isOutputShaderIoBlock = isShaderIoBlock && IsShaderOut(typeQualifier.qualifier);
+ if (fieldType->isInvariant() && !isOutputShaderIoBlock)
+ {
+ error(field->line(), "invalid qualifier on interface block member", "invariant");
+ }
+
+ // check layout qualifiers
+ TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
+ checkIndexIsNotSpecified(field->line(), fieldLayoutQualifier.index);
+ checkBindingIsNotSpecified(field->line(), fieldLayoutQualifier.binding);
+
+ if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
+ {
+ error(field->line(), "invalid layout qualifier: cannot be used here",
+ getBlockStorageString(fieldLayoutQualifier.blockStorage));
+ }
+
+ if (fieldLayoutQualifier.matrixPacking == EmpUnspecified)
+ {
+ fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
+ }
+ else if (!fieldType->isMatrix() && fieldType->getBasicType() != EbtStruct)
+ {
+ warning(field->line(),
+ "extraneous layout qualifier: only has an effect on matrix types",
+ getMatrixPackingString(fieldLayoutQualifier.matrixPacking));
+ }
+
+ fieldType->setLayoutQualifier(fieldLayoutQualifier);
+
+ if (mShaderVersion < 310 || memberIndex != fieldList->size() - 1u ||
+ typeQualifier.qualifier != EvqBuffer)
+ {
+ // ESSL 3.10 spec section 4.1.9 allows for runtime-sized arrays.
+ checkIsNotUnsizedArray(field->line(),
+ "array members of interface blocks must specify a size",
+ field->name(), field->type());
+ }
+
+ if (typeQualifier.qualifier == EvqBuffer)
+ {
+ // set memory qualifiers
+ // GLSL ES 3.10 session 4.9 [Memory Access Qualifiers]. When a block declaration is
+ // qualified with a memory qualifier, it is as if all of its members were declared with
+ // the same memory qualifier.
+ const TMemoryQualifier &blockMemoryQualifier = typeQualifier.memoryQualifier;
+ TMemoryQualifier fieldMemoryQualifier = fieldType->getMemoryQualifier();
+ fieldMemoryQualifier.readonly |= blockMemoryQualifier.readonly;
+ fieldMemoryQualifier.writeonly |= blockMemoryQualifier.writeonly;
+ fieldMemoryQualifier.coherent |= blockMemoryQualifier.coherent;
+ fieldMemoryQualifier.restrictQualifier |= blockMemoryQualifier.restrictQualifier;
+ fieldMemoryQualifier.volatileQualifier |= blockMemoryQualifier.volatileQualifier;
+ // TODO(jiajia.qin@intel.com): Decide whether if readonly and writeonly buffer variable
+ // is legal. See bug https://github.com/KhronosGroup/OpenGL-API/issues/7
+ fieldType->setMemoryQualifier(fieldMemoryQualifier);
+ }
+ }
+
+ SymbolType instanceSymbolType = SymbolType::UserDefined;
+ if (isGLPerVertex)
+ {
+ instanceSymbolType = SymbolType::BuiltIn;
+ }
+ TInterfaceBlock *interfaceBlock = new TInterfaceBlock(&symbolTable, blockName, fieldList,
+ blockLayoutQualifier, instanceSymbolType);
+ if (!symbolTable.declare(interfaceBlock) && isUniformOrBuffer)
+ {
+ error(nameLine, "redefinition of an interface block name", blockName);
+ }
+
+ TType *interfaceBlockType =
+ new TType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier);
+ if (arraySizes)
+ {
+ interfaceBlockType->makeArrays(*arraySizes);
+
+ checkGeometryShaderInputAndSetArraySize(instanceLine, instanceName, interfaceBlockType);
+ checkTessellationShaderUnsizedArraysAndSetSize(instanceLine, instanceName,
+ interfaceBlockType);
+ }
+
+ // The instance variable gets created to refer to the interface block type from the AST
+ // regardless of if there's an instance name. It's created as an empty symbol if there is no
+ // instance name.
+ TVariable *instanceVariable =
+ new TVariable(&symbolTable, instanceName, interfaceBlockType,
+ instanceName.empty() ? SymbolType::Empty : SymbolType::UserDefined);
+
+ if (instanceVariable->symbolType() == SymbolType::Empty)
+ {
+ // define symbols for the members of the interface block
+ for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
+ {
+ TField *field = (*fieldList)[memberIndex];
+ TType *fieldType = new TType(*field->type());
+
+ // set parent pointer of the field variable
+ fieldType->setInterfaceBlockField(interfaceBlock, memberIndex);
+
+ fieldType->setQualifier(typeQualifier.qualifier);
+
+ SymbolType symbolType = SymbolType::UserDefined;
+ if (field->name() == "gl_Position" || field->name() == "gl_PointSize" ||
+ field->name() == "gl_ClipDistance" || field->name() == "gl_CullDistance")
+ {
+ // These builtins can be redifined only when used within a redefiend gl_PerVertex
+ // block
+ if (interfaceBlock->name() != "gl_PerVertex")
+ {
+ error(field->line(), "redefinition in an invalid interface block",
+ field->name());
+ }
+ symbolType = SymbolType::BuiltIn;
+ }
+ TVariable *fieldVariable =
+ new TVariable(&symbolTable, field->name(), fieldType, symbolType);
+ if (!symbolTable.declare(fieldVariable))
+ {
+ error(field->line(), "redefinition of an interface block member name",
+ field->name());
+ }
+ }
+ }
+ else
+ {
+ checkIsNotReserved(instanceLine, instanceName);
+
+ // add a symbol for this interface block
+ if (!symbolTable.declare(instanceVariable))
+ {
+ error(instanceLine, "redefinition of an interface block instance name", instanceName);
+ }
+ }
+
+ TIntermSymbol *blockSymbol = new TIntermSymbol(instanceVariable);
+ blockSymbol->setLine(typeQualifier.line);
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->appendDeclarator(blockSymbol);
+ declaration->setLine(nameLine);
+
+ exitStructDeclaration();
+ return declaration;
+}
+
+void TParseContext::enterStructDeclaration(const TSourceLoc &line,
+ const ImmutableString &identifier)
+{
+ ++mStructNestingLevel;
+
+ // Embedded structure definitions are not supported per GLSL ES spec.
+ // ESSL 1.00.17 section 10.9. ESSL 3.00.6 section 12.11.
+ if (mStructNestingLevel > 1)
+ {
+ error(line, "Embedded struct definitions are not allowed", "struct");
+ }
+}
+
+void TParseContext::exitStructDeclaration()
+{
+ --mStructNestingLevel;
+}
+
+void TParseContext::checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field)
+{
+ if (!sh::IsWebGLBasedSpec(mShaderSpec))
+ {
+ return;
+ }
+
+ if (field.type()->getBasicType() != EbtStruct)
+ {
+ return;
+ }
+
+ // We're already inside a structure definition at this point, so add
+ // one to the field's struct nesting.
+ if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting)
+ {
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
+ if (field.type()->getStruct()->symbolType() == SymbolType::Empty)
+ {
+ // This may happen in case there are nested struct definitions. While they are also
+ // invalid GLSL, they don't cause a syntax error.
+ reasonStream << "Struct nesting";
+ }
+ else
+ {
+ reasonStream << "Reference of struct type " << field.type()->getStruct()->name();
+ }
+ reasonStream << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting;
+ std::string reason = reasonStream.str();
+ error(line, reason.c_str(), field.name());
+ return;
+ }
+}
+
+//
+// Parse an array index expression
+//
+TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
+ const TSourceLoc &location,
+ TIntermTyped *indexExpression)
+{
+ if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
+ {
+ if (baseExpression->getAsSymbolNode())
+ {
+ error(location, " left of '[' is not of type array, matrix, or vector ",
+ baseExpression->getAsSymbolNode()->getName());
+ }
+ else
+ {
+ error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
+ }
+
+ return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
+ }
+
+ if (baseExpression->getQualifier() == EvqPerVertexIn)
+ {
+ if (mGeometryShaderInputPrimitiveType == EptUndefined &&
+ mShaderType == GL_GEOMETRY_SHADER_EXT)
+ {
+ error(location, "missing input primitive declaration before indexing gl_in.", "[");
+ return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
+ }
+ }
+
+ TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
+
+ // ES3.2 or ES3.1's EXT_gpu_shader5 allow dynamically uniform expressions to be used as indices
+ // of opaque types (samplers and atomic counters) as well as UBOs, but not SSBOs and images.
+ bool allowUniformIndices =
+ mShaderVersion >= 320 || isExtensionEnabled(TExtension::EXT_gpu_shader5);
+
+ // ANGLE should be able to fold any constant expressions resulting in an integer - but to be
+ // safe we don't treat "EvqConst" that's evaluated according to the spec as being sufficient
+ // for constness. Some interpretations of the spec have allowed constant expressions with side
+ // effects - like array length() method on a non-constant array.
+ if (indexExpression->getQualifier() != EvqConst || indexConstantUnion == nullptr)
+ {
+ if (baseExpression->isInterfaceBlock())
+ {
+ switch (baseExpression->getQualifier())
+ {
+ case EvqPerVertexIn:
+ break;
+ case EvqUniform:
+ if (!allowUniformIndices)
+ {
+ error(location,
+ "array indexes for uniform block arrays must be constant integral "
+ "expressions",
+ "[");
+ }
+ break;
+ case EvqBuffer:
+ error(location,
+ "array indexes for shader storage block arrays must be constant integral "
+ "expressions",
+ "[");
+ break;
+ default:
+ // It's ok for shader I/O blocks to be dynamically indexed
+ if (!IsShaderIoBlock(baseExpression->getQualifier()) &&
+ baseExpression->getQualifier() != EvqPatchIn &&
+ baseExpression->getQualifier() != EvqPatchOut)
+ {
+ // We can reach here only in error cases.
+ ASSERT(mDiagnostics->numErrors() > 0);
+ }
+ break;
+ }
+ }
+ else if (baseExpression->getQualifier() == EvqFragmentOut)
+ {
+ error(location,
+ "array indexes for fragment outputs must be constant integral expressions", "[");
+ }
+ else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData)
+ {
+ error(location, "array index for gl_FragData must be constant zero", "[");
+ }
+ else if (baseExpression->isArray())
+ {
+ TBasicType elementType = baseExpression->getType().getBasicType();
+
+ // Note: In Section 12.30 of the ESSL 3.00 spec on p143-144:
+ //
+ // Indexing of arrays of samplers by constant-index-expressions is
+ // supported in GLSL ES 1.00. A constant-index-expression is an
+ // expression formed from constant-expressions and certain loop indices,
+ // defined for a subset of loop constructs. Should this functionality be
+ // included in GLSL ES 3.00?
+ //
+ // RESOLUTION: No. Arrays of samplers may only be indexed by constant-
+ // integral-expressions.
+ if (IsSampler(elementType) && !allowUniformIndices && mShaderVersion > 100)
+ {
+ error(location, "array index for samplers must be constant integral expressions",
+ "[");
+ }
+ else if (IsImage(elementType))
+ {
+ error(location,
+ "array indexes for image arrays must be constant integral expressions", "[");
+ }
+ }
+ }
+
+ if (indexConstantUnion)
+ {
+ // If an out-of-range index is not qualified as constant, the behavior in the spec is
+ // undefined. This applies even if ANGLE has been able to constant fold it (ANGLE may
+ // constant fold expressions that are not constant expressions). The most compatible way to
+ // handle this case is to report a warning instead of an error and force the index to be in
+ // the correct range.
+ bool outOfRangeIndexIsError = indexExpression->getQualifier() == EvqConst;
+ int index = 0;
+ if (indexConstantUnion->getBasicType() == EbtInt)
+ {
+ index = indexConstantUnion->getIConst(0);
+ }
+ else if (indexConstantUnion->getBasicType() == EbtUInt)
+ {
+ index = static_cast<int>(indexConstantUnion->getUConst(0));
+ }
+
+ int safeIndex = -1;
+
+ if (index < 0)
+ {
+ outOfRangeError(outOfRangeIndexIsError, location, "index expression is negative", "[]");
+ safeIndex = 0;
+ }
+
+ if (!baseExpression->getType().isUnsizedArray())
+ {
+ if (baseExpression->isArray())
+ {
+ if (baseExpression->getQualifier() == EvqFragData && index > 0)
+ {
+ if (!isExtensionEnabled(TExtension::EXT_draw_buffers))
+ {
+ outOfRangeError(outOfRangeIndexIsError, location,
+ "array index for gl_FragData must be zero when "
+ "GL_EXT_draw_buffers is disabled",
+ "[]");
+ safeIndex = 0;
+ }
+ }
+ }
+ // Only do generic out-of-range check if similar error hasn't already been reported.
+ if (safeIndex < 0)
+ {
+ if (baseExpression->isArray())
+ {
+ safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
+ baseExpression->getOutermostArraySize(),
+ "array index out of range");
+ }
+ else if (baseExpression->isMatrix())
+ {
+ safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
+ baseExpression->getType().getCols(),
+ "matrix field selection out of range");
+ }
+ else
+ {
+ ASSERT(baseExpression->isVector());
+ safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
+ baseExpression->getType().getNominalSize(),
+ "vector field selection out of range");
+ }
+ }
+
+ ASSERT(safeIndex >= 0);
+ // Data of constant unions can't be changed, because it may be shared with other
+ // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
+ // sanitized object.
+ if (safeIndex != index || indexConstantUnion->getBasicType() != EbtInt)
+ {
+ TConstantUnion *safeConstantUnion = new TConstantUnion();
+ safeConstantUnion->setIConst(safeIndex);
+ indexExpression =
+ new TIntermConstantUnion(safeConstantUnion, TType(indexExpression->getType()));
+ }
+
+ TIntermBinary *node =
+ new TIntermBinary(EOpIndexDirect, baseExpression, indexExpression);
+ node->setLine(location);
+ return expressionOrFoldedResult(node);
+ }
+ }
+
+ markStaticReadIfSymbol(indexExpression);
+ TIntermBinary *node = new TIntermBinary(EOpIndexIndirect, baseExpression, indexExpression);
+ node->setLine(location);
+ // Indirect indexing can never be constant folded.
+ return node;
+}
+
+int TParseContext::checkIndexLessThan(bool outOfRangeIndexIsError,
+ const TSourceLoc &location,
+ int index,
+ int arraySize,
+ const char *reason)
+{
+ // Should not reach here with an unsized / runtime-sized array.
+ ASSERT(arraySize > 0);
+ // A negative index should already have been checked.
+ ASSERT(index >= 0);
+ if (index >= arraySize)
+ {
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
+ reasonStream << reason << " '" << index << "'";
+ std::string token = reasonStream.str();
+ outOfRangeError(outOfRangeIndexIsError, location, reason, "[]");
+ return arraySize - 1;
+ }
+ return index;
+}
+
+TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression,
+ const TSourceLoc &dotLocation,
+ const ImmutableString &fieldString,
+ const TSourceLoc &fieldLocation)
+{
+ if (baseExpression->isArray())
+ {
+ error(fieldLocation, "cannot apply dot operator to an array", ".");
+ return baseExpression;
+ }
+
+ if (baseExpression->isVector())
+ {
+ TVector<int> fieldOffsets;
+ if (!parseVectorFields(fieldLocation, fieldString, baseExpression->getNominalSize(),
+ &fieldOffsets))
+ {
+ fieldOffsets.resize(1);
+ fieldOffsets[0] = 0;
+ }
+ TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldOffsets);
+ node->setLine(dotLocation);
+
+ return node->fold(mDiagnostics);
+ }
+ else if (baseExpression->getBasicType() == EbtStruct)
+ {
+ const TFieldList &fields = baseExpression->getType().getStruct()->fields();
+ if (fields.empty())
+ {
+ error(dotLocation, "structure has no fields", "Internal Error");
+ return baseExpression;
+ }
+ else
+ {
+ bool fieldFound = false;
+ unsigned int i;
+ for (i = 0; i < fields.size(); ++i)
+ {
+ if (fields[i]->name() == fieldString)
+ {
+ fieldFound = true;
+ break;
+ }
+ }
+ if (fieldFound)
+ {
+ TIntermTyped *index = CreateIndexNode(i);
+ index->setLine(fieldLocation);
+ TIntermBinary *node =
+ new TIntermBinary(EOpIndexDirectStruct, baseExpression, index);
+ node->setLine(dotLocation);
+ return expressionOrFoldedResult(node);
+ }
+ else
+ {
+ error(dotLocation, " no such field in structure", fieldString);
+ return baseExpression;
+ }
+ }
+ }
+ else if (baseExpression->isInterfaceBlock())
+ {
+ const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
+ if (fields.empty())
+ {
+ error(dotLocation, "interface block has no fields", "Internal Error");
+ return baseExpression;
+ }
+ else
+ {
+ bool fieldFound = false;
+ unsigned int i;
+ for (i = 0; i < fields.size(); ++i)
+ {
+ if (fields[i]->name() == fieldString)
+ {
+ fieldFound = true;
+ break;
+ }
+ }
+ if (fieldFound)
+ {
+ TIntermTyped *index = CreateIndexNode(i);
+ index->setLine(fieldLocation);
+ TIntermBinary *node =
+ new TIntermBinary(EOpIndexDirectInterfaceBlock, baseExpression, index);
+ node->setLine(dotLocation);
+ // Indexing interface blocks can never be constant folded.
+ return node;
+ }
+ else
+ {
+ error(dotLocation, " no such field in interface block", fieldString);
+ return baseExpression;
+ }
+ }
+ }
+ else
+ {
+ if (mShaderVersion < 300)
+ {
+ error(dotLocation, " field selection requires structure or vector on left hand side",
+ fieldString);
+ }
+ else
+ {
+ error(dotLocation,
+ " field selection requires structure, vector, or interface block on left hand "
+ "side",
+ fieldString);
+ }
+ return baseExpression;
+ }
+}
+
+TLayoutQualifier TParseContext::parseLayoutQualifier(const ImmutableString &qualifierType,
+ const TSourceLoc &qualifierTypeLine)
+{
+ TLayoutQualifier qualifier = TLayoutQualifier::Create();
+
+ if (qualifierType == "shared")
+ {
+ if (sh::IsWebGLBasedSpec(mShaderSpec))
+ {
+ error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "shared");
+ }
+ qualifier.blockStorage = EbsShared;
+ }
+ else if (qualifierType == "packed")
+ {
+ if (sh::IsWebGLBasedSpec(mShaderSpec))
+ {
+ error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "packed");
+ }
+ qualifier.blockStorage = EbsPacked;
+ }
+ else if (qualifierType == "std430")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.blockStorage = EbsStd430;
+ }
+ else if (qualifierType == "std140")
+ {
+ qualifier.blockStorage = EbsStd140;
+ }
+ else if (qualifierType == "row_major")
+ {
+ qualifier.matrixPacking = EmpRowMajor;
+ }
+ else if (qualifierType == "column_major")
+ {
+ qualifier.matrixPacking = EmpColumnMajor;
+ }
+ else if (qualifierType == "location")
+ {
+ error(qualifierTypeLine, "invalid layout qualifier: location requires an argument",
+ qualifierType);
+ }
+ else if (qualifierType == "yuv" && mShaderType == GL_FRAGMENT_SHADER)
+ {
+ if (checkCanUseExtension(qualifierTypeLine, TExtension::EXT_YUV_target))
+ {
+ qualifier.yuv = true;
+ }
+ }
+ else if (qualifierType == "early_fragment_tests")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.earlyFragmentTests = true;
+ }
+ else if (qualifierType == "rgba32f")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA32F;
+ }
+ else if (qualifierType == "rgba16f")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA16F;
+ }
+ else if (qualifierType == "r32f")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ qualifier.imageInternalFormat = EiifR32F;
+ }
+ else if (qualifierType == "rgba8")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ qualifier.imageInternalFormat = EiifRGBA8;
+ }
+ else if (qualifierType == "rgba8_snorm")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA8_SNORM;
+ }
+ else if (qualifierType == "rgba32i")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA32I;
+ }
+ else if (qualifierType == "rgba16i")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA16I;
+ }
+ else if (qualifierType == "rgba8i")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ qualifier.imageInternalFormat = EiifRGBA8I;
+ }
+ else if (qualifierType == "r32i")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifR32I;
+ }
+ else if (qualifierType == "rgba32ui")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA32UI;
+ }
+ else if (qualifierType == "rgba16ui")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA16UI;
+ }
+ else if (qualifierType == "rgba8ui")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ qualifier.imageInternalFormat = EiifRGBA8UI;
+ }
+ else if (qualifierType == "r32ui")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ qualifier.imageInternalFormat = EiifR32UI;
+ }
+ else if (mShaderType == GL_GEOMETRY_SHADER_EXT &&
+ (mShaderVersion >= 320 ||
+ (checkCanUseOneOfExtensions(
+ qualifierTypeLine,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}}) &&
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310))))
+ {
+ if (qualifierType == "points")
+ {
+ qualifier.primitiveType = EptPoints;
+ }
+ else if (qualifierType == "lines")
+ {
+ qualifier.primitiveType = EptLines;
+ }
+ else if (qualifierType == "lines_adjacency")
+ {
+ qualifier.primitiveType = EptLinesAdjacency;
+ }
+ else if (qualifierType == "triangles")
+ {
+ qualifier.primitiveType = EptTriangles;
+ }
+ else if (qualifierType == "triangles_adjacency")
+ {
+ qualifier.primitiveType = EptTrianglesAdjacency;
+ }
+ else if (qualifierType == "line_strip")
+ {
+ qualifier.primitiveType = EptLineStrip;
+ }
+ else if (qualifierType == "triangle_strip")
+ {
+ qualifier.primitiveType = EptTriangleStrip;
+ }
+ else
+ {
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
+ }
+ }
+ else if (mShaderType == GL_TESS_EVALUATION_SHADER_EXT &&
+ (mShaderVersion >= 320 ||
+ (checkCanUseExtension(qualifierTypeLine, TExtension::EXT_tessellation_shader) &&
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310))))
+ {
+ if (qualifierType == "triangles")
+ {
+ qualifier.tesPrimitiveType = EtetTriangles;
+ }
+ else if (qualifierType == "quads")
+ {
+ qualifier.tesPrimitiveType = EtetQuads;
+ }
+ else if (qualifierType == "isolines")
+ {
+ qualifier.tesPrimitiveType = EtetIsolines;
+ }
+ else if (qualifierType == "equal_spacing")
+ {
+ qualifier.tesVertexSpacingType = EtetEqualSpacing;
+ }
+ else if (qualifierType == "fractional_even_spacing")
+ {
+ qualifier.tesVertexSpacingType = EtetFractionalEvenSpacing;
+ }
+ else if (qualifierType == "fractional_odd_spacing")
+ {
+ qualifier.tesVertexSpacingType = EtetFractionalOddSpacing;
+ }
+ else if (qualifierType == "cw")
+ {
+ qualifier.tesOrderingType = EtetCw;
+ }
+ else if (qualifierType == "ccw")
+ {
+ qualifier.tesOrderingType = EtetCcw;
+ }
+ else if (qualifierType == "point_mode")
+ {
+ qualifier.tesPointType = EtetPointMode;
+ }
+ else
+ {
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
+ }
+ }
+ else if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ if (qualifierType == "noncoherent")
+ {
+ if (checkCanUseOneOfExtensions(
+ qualifierTypeLine,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_shader_framebuffer_fetch,
+ TExtension::EXT_shader_framebuffer_fetch_non_coherent}}))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 100);
+ qualifier.noncoherent = true;
+ }
+ }
+ else if (qualifierType == "blend_support_multiply")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Multiply, &qualifier);
+ }
+ else if (qualifierType == "blend_support_screen")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Screen, &qualifier);
+ }
+ else if (qualifierType == "blend_support_overlay")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Overlay, &qualifier);
+ }
+ else if (qualifierType == "blend_support_darken")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Darken, &qualifier);
+ }
+ else if (qualifierType == "blend_support_lighten")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Lighten, &qualifier);
+ }
+ else if (qualifierType == "blend_support_colordodge")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Colordodge, &qualifier);
+ }
+ else if (qualifierType == "blend_support_colorburn")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Colorburn, &qualifier);
+ }
+ else if (qualifierType == "blend_support_hardlight")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Hardlight, &qualifier);
+ }
+ else if (qualifierType == "blend_support_softlight")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Softlight, &qualifier);
+ }
+ else if (qualifierType == "blend_support_difference")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Difference, &qualifier);
+ }
+ else if (qualifierType == "blend_support_exclusion")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Exclusion, &qualifier);
+ }
+ else if (qualifierType == "blend_support_hsl_hue")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::HslHue, &qualifier);
+ }
+ else if (qualifierType == "blend_support_hsl_saturation")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::HslSaturation, &qualifier);
+ }
+ else if (qualifierType == "blend_support_hsl_color")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::HslColor, &qualifier);
+ }
+ else if (qualifierType == "blend_support_hsl_luminosity")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::HslLuminosity, &qualifier);
+ }
+ else if (qualifierType == "blend_support_all_equations")
+ {
+ qualifier.advancedBlendEquations.setAll();
+ }
+ else
+ {
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
+ }
+
+ if (qualifier.advancedBlendEquations.any() && mShaderVersion < 320)
+ {
+ if (!checkCanUseExtension(qualifierTypeLine, TExtension::KHR_blend_equation_advanced))
+ {
+ qualifier.advancedBlendEquations.reset();
+ }
+ }
+ }
+ else
+ {
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
+ }
+
+ return qualifier;
+}
+
+void TParseContext::parseLocalSize(const ImmutableString &qualifierType,
+ const TSourceLoc &qualifierTypeLine,
+ int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ size_t index,
+ sh::WorkGroupSize *localSize)
+{
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ if (intValue < 1)
+ {
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
+ reasonStream << "out of range: " << getWorkGroupSizeString(index) << " must be positive";
+ std::string reason = reasonStream.str();
+ error(intValueLine, reason.c_str(), intValueString.c_str());
+ }
+ (*localSize)[index] = intValue;
+}
+
+void TParseContext::parseNumViews(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numViews)
+{
+ // This error is only specified in WebGL, but tightens unspecified behavior in the native
+ // specification.
+ if (intValue < 1)
+ {
+ error(intValueLine, "out of range: num_views must be positive", intValueString.c_str());
+ }
+ *numViews = intValue;
+}
+
+void TParseContext::parseInvocations(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numInvocations)
+{
+ // Although SPEC isn't clear whether invocations can be less than 1, we add this limit because
+ // it doesn't make sense to accept invocations <= 0.
+ if (intValue < 1 || intValue > mMaxGeometryShaderInvocations)
+ {
+ error(intValueLine,
+ "out of range: invocations must be in the range of [1, "
+ "MAX_GEOMETRY_SHADER_INVOCATIONS_OES]",
+ intValueString.c_str());
+ }
+ else
+ {
+ *numInvocations = intValue;
+ }
+}
+
+void TParseContext::parseMaxVertices(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *maxVertices)
+{
+ // Although SPEC isn't clear whether max_vertices can be less than 0, we add this limit because
+ // it doesn't make sense to accept max_vertices < 0.
+ if (intValue < 0 || intValue > mMaxGeometryShaderMaxVertices)
+ {
+ error(
+ intValueLine,
+ "out of range: max_vertices must be in the range of [0, gl_MaxGeometryOutputVertices]",
+ intValueString.c_str());
+ }
+ else
+ {
+ *maxVertices = intValue;
+ }
+}
+
+void TParseContext::parseVertices(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *vertices)
+{
+ if (intValue < 1 || intValue > mMaxPatchVertices)
+ {
+ error(intValueLine,
+ "out of range : vertices must be in the range of [1, gl_MaxPatchVertices]",
+ intValueString.c_str());
+ }
+ else
+ {
+ *vertices = intValue;
+ }
+}
+
+void TParseContext::parseIndexLayoutQualifier(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *index)
+{
+ // EXT_blend_func_extended specifies that most validation should happen at link time, but since
+ // we're validating output variable locations at compile time, it makes sense to validate that
+ // index is 0 or 1 also at compile time. Also since we use "-1" as a placeholder for unspecified
+ // index, we can't accept it here.
+ if (intValue < 0 || intValue > 1)
+ {
+ error(intValueLine, "out of range: index layout qualifier can only be 0 or 1",
+ intValueString.c_str());
+ }
+ else
+ {
+ *index = intValue;
+ }
+}
+
+TLayoutQualifier TParseContext::parseLayoutQualifier(const ImmutableString &qualifierType,
+ const TSourceLoc &qualifierTypeLine,
+ int intValue,
+ const TSourceLoc &intValueLine)
+{
+ TLayoutQualifier qualifier = TLayoutQualifier::Create();
+
+ std::string intValueString = Str(intValue);
+
+ if (qualifierType == "location")
+ {
+ // must check that location is non-negative
+ if (intValue < 0)
+ {
+ error(intValueLine, "out of range: location must be non-negative",
+ intValueString.c_str());
+ }
+ else
+ {
+ qualifier.location = intValue;
+ qualifier.locationsSpecified = 1;
+ }
+ }
+ else if (qualifierType == "binding")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ if (intValue < 0)
+ {
+ error(intValueLine, "out of range: binding must be non-negative",
+ intValueString.c_str());
+ }
+ else
+ {
+ qualifier.binding = intValue;
+ }
+ }
+ else if (qualifierType == "offset")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ if (intValue < 0)
+ {
+ error(intValueLine, "out of range: offset must be non-negative",
+ intValueString.c_str());
+ }
+ else
+ {
+ qualifier.offset = intValue;
+ }
+ }
+ else if (qualifierType == "local_size_x")
+ {
+ parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 0u,
+ &qualifier.localSize);
+ }
+ else if (qualifierType == "local_size_y")
+ {
+ parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 1u,
+ &qualifier.localSize);
+ }
+ else if (qualifierType == "local_size_z")
+ {
+ parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 2u,
+ &qualifier.localSize);
+ }
+ else if (qualifierType == "num_views" && mShaderType == GL_VERTEX_SHADER)
+ {
+ if (checkCanUseOneOfExtensions(
+ qualifierTypeLine, std::array<TExtension, 2u>{
+ {TExtension::OVR_multiview, TExtension::OVR_multiview2}}))
+ {
+ parseNumViews(intValue, intValueLine, intValueString, &qualifier.numViews);
+ }
+ }
+ else if (qualifierType == "invocations" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+ (mShaderVersion >= 320 ||
+ checkCanUseOneOfExtensions(
+ qualifierTypeLine,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}})))
+ {
+ parseInvocations(intValue, intValueLine, intValueString, &qualifier.invocations);
+ }
+ else if (qualifierType == "max_vertices" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+ (mShaderVersion >= 320 ||
+ checkCanUseOneOfExtensions(
+ qualifierTypeLine,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}})))
+ {
+ parseMaxVertices(intValue, intValueLine, intValueString, &qualifier.maxVertices);
+ }
+ else if (qualifierType == "index" && mShaderType == GL_FRAGMENT_SHADER &&
+ checkCanUseExtension(qualifierTypeLine, TExtension::EXT_blend_func_extended))
+ {
+ parseIndexLayoutQualifier(intValue, intValueLine, intValueString, &qualifier.index);
+ }
+ else if (qualifierType == "vertices" && mShaderType == GL_TESS_CONTROL_SHADER_EXT &&
+ (mShaderVersion >= 320 ||
+ checkCanUseExtension(qualifierTypeLine, TExtension::EXT_tessellation_shader)))
+ {
+ parseVertices(intValue, intValueLine, intValueString, &qualifier.vertices);
+ }
+ else
+ {
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
+ }
+
+ return qualifier;
+}
+
+TTypeQualifierBuilder *TParseContext::createTypeQualifierBuilder(const TSourceLoc &loc)
+{
+ return new TTypeQualifierBuilder(
+ new TStorageQualifierWrapper(symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary, loc),
+ mShaderVersion);
+}
+
+TStorageQualifierWrapper *TParseContext::parseGlobalStorageQualifier(TQualifier qualifier,
+ const TSourceLoc &loc)
+{
+ checkIsAtGlobalLevel(loc, getQualifierString(qualifier));
+ return new TStorageQualifierWrapper(qualifier, loc);
+}
+
+TStorageQualifierWrapper *TParseContext::parseVaryingQualifier(const TSourceLoc &loc)
+{
+ if (getShaderType() == GL_VERTEX_SHADER)
+ {
+ return parseGlobalStorageQualifier(EvqVaryingOut, loc);
+ }
+ return parseGlobalStorageQualifier(EvqVaryingIn, loc);
+}
+
+TStorageQualifierWrapper *TParseContext::parseInQualifier(const TSourceLoc &loc)
+{
+ if (declaringFunction())
+ {
+ return new TStorageQualifierWrapper(EvqParamIn, loc);
+ }
+
+ switch (getShaderType())
+ {
+ case GL_VERTEX_SHADER:
+ {
+ if (mShaderVersion < 300 && !anyMultiviewExtensionAvailable() &&
+ !IsDesktopGLSpec(mShaderSpec))
+ {
+ error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
+ }
+ return new TStorageQualifierWrapper(EvqVertexIn, loc);
+ }
+ case GL_FRAGMENT_SHADER:
+ {
+ if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
+ {
+ error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
+ }
+ return new TStorageQualifierWrapper(EvqFragmentIn, loc);
+ }
+ case GL_COMPUTE_SHADER:
+ {
+ return new TStorageQualifierWrapper(EvqComputeIn, loc);
+ }
+ case GL_GEOMETRY_SHADER:
+ {
+ return new TStorageQualifierWrapper(EvqGeometryIn, loc);
+ }
+ case GL_TESS_CONTROL_SHADER:
+ {
+ return new TStorageQualifierWrapper(EvqTessControlIn, loc);
+ }
+ case GL_TESS_EVALUATION_SHADER:
+ {
+ return new TStorageQualifierWrapper(EvqTessEvaluationIn, loc);
+ }
+ default:
+ {
+ UNREACHABLE();
+ return new TStorageQualifierWrapper(EvqLast, loc);
+ }
+ }
+}
+
+TStorageQualifierWrapper *TParseContext::parseOutQualifier(const TSourceLoc &loc)
+{
+ if (declaringFunction())
+ {
+ return new TStorageQualifierWrapper(EvqParamOut, loc);
+ }
+ switch (getShaderType())
+ {
+ case GL_VERTEX_SHADER:
+ {
+ if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
+ {
+ error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "out");
+ }
+ return new TStorageQualifierWrapper(EvqVertexOut, loc);
+ }
+ case GL_FRAGMENT_SHADER:
+ {
+ if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
+ {
+ error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "out");
+ }
+ return new TStorageQualifierWrapper(EvqFragmentOut, loc);
+ }
+ case GL_COMPUTE_SHADER:
+ {
+ error(loc, "storage qualifier isn't supported in compute shaders", "out");
+ return new TStorageQualifierWrapper(EvqParamOut, loc);
+ }
+ case GL_GEOMETRY_SHADER_EXT:
+ {
+ return new TStorageQualifierWrapper(EvqGeometryOut, loc);
+ }
+ case GL_TESS_CONTROL_SHADER_EXT:
+ {
+ return new TStorageQualifierWrapper(EvqTessControlOut, loc);
+ }
+ case GL_TESS_EVALUATION_SHADER_EXT:
+ {
+ return new TStorageQualifierWrapper(EvqTessEvaluationOut, loc);
+ }
+ default:
+ {
+ UNREACHABLE();
+ return new TStorageQualifierWrapper(EvqLast, loc);
+ }
+ }
+}
+
+TStorageQualifierWrapper *TParseContext::parseInOutQualifier(const TSourceLoc &loc)
+{
+ if (!declaringFunction())
+ {
+ if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
+ {
+ error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "inout");
+ }
+
+ if (getShaderType() != GL_FRAGMENT_SHADER)
+ {
+ error(loc, "storage qualifier isn't supported in non-fragment shaders", "inout");
+ }
+
+ if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
+ isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent))
+ {
+ return new TStorageQualifierWrapper(EvqFragmentInOut, loc);
+ }
+
+ error(loc,
+ "invalid qualifier: can be used with either function parameters or the variables for "
+ "fetching input attachment data",
+ "inout");
+ }
+ return new TStorageQualifierWrapper(EvqParamInOut, loc);
+}
+
+TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier,
+ TLayoutQualifier rightQualifier,
+ const TSourceLoc &rightQualifierLocation)
+{
+ return sh::JoinLayoutQualifiers(leftQualifier, rightQualifier, rightQualifierLocation,
+ mDiagnostics);
+}
+
+TDeclarator *TParseContext::parseStructDeclarator(const ImmutableString &identifier,
+ const TSourceLoc &loc)
+{
+ return new TDeclarator(identifier, loc);
+}
+
+TDeclarator *TParseContext::parseStructArrayDeclarator(const ImmutableString &identifier,
+ const TSourceLoc &loc,
+ const TVector<unsigned int> *arraySizes)
+{
+ return new TDeclarator(identifier, arraySizes, loc);
+}
+
+void TParseContext::checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
+ const TFieldList::const_iterator end,
+ const ImmutableString &name,
+ const TSourceLoc &location)
+{
+ for (auto fieldIter = begin; fieldIter != end; ++fieldIter)
+ {
+ if ((*fieldIter)->name() == name)
+ {
+ error(location, "duplicate field name in structure", name);
+ }
+ }
+}
+
+TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location)
+{
+ for (TFieldList::const_iterator fieldIter = fields->begin(); fieldIter != fields->end();
+ ++fieldIter)
+ {
+ checkDoesNotHaveDuplicateFieldName(fields->begin(), fieldIter, (*fieldIter)->name(),
+ location);
+ }
+ return fields;
+}
+
+TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields,
+ const TFieldList *newlyAddedFields,
+ const TSourceLoc &location)
+{
+ for (TField *field : *newlyAddedFields)
+ {
+ checkDoesNotHaveDuplicateFieldName(processedFields->begin(), processedFields->end(),
+ field->name(), location);
+ processedFields->push_back(field);
+ }
+ return processedFields;
+}
+
+TFieldList *TParseContext::addStructDeclaratorListWithQualifiers(
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ TPublicType *typeSpecifier,
+ const TDeclaratorList *declaratorList)
+{
+ TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
+
+ typeSpecifier->qualifier = typeQualifier.qualifier;
+ typeSpecifier->layoutQualifier = typeQualifier.layoutQualifier;
+ typeSpecifier->memoryQualifier = typeQualifier.memoryQualifier;
+ typeSpecifier->invariant = typeQualifier.invariant;
+ typeSpecifier->precise = typeQualifier.precise;
+ if (typeQualifier.precision != EbpUndefined)
+ {
+ typeSpecifier->precision = typeQualifier.precision;
+ }
+ return addStructDeclaratorList(*typeSpecifier, declaratorList);
+}
+
+TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier,
+ const TDeclaratorList *declaratorList)
+{
+ checkPrecisionSpecified(typeSpecifier.getLine(), typeSpecifier.precision,
+ typeSpecifier.getBasicType());
+
+ checkIsNonVoid(typeSpecifier.getLine(), (*declaratorList)[0]->name(),
+ typeSpecifier.getBasicType());
+
+ checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), typeSpecifier.layoutQualifier);
+ checkEarlyFragmentTestsIsNotSpecified(typeSpecifier.getLine(),
+ typeSpecifier.layoutQualifier.earlyFragmentTests);
+ checkNoncoherentIsNotSpecified(typeSpecifier.getLine(),
+ typeSpecifier.layoutQualifier.noncoherent);
+
+ TFieldList *fieldList = new TFieldList();
+
+ for (const TDeclarator *declarator : *declaratorList)
+ {
+ TType *type = new TType(typeSpecifier);
+ if (declarator->isArray())
+ {
+ // Don't allow arrays of arrays in ESSL < 3.10.
+ checkArrayElementIsNotArray(typeSpecifier.getLine(), typeSpecifier);
+ type->makeArrays(*declarator->arraySizes());
+ }
+
+ SymbolType symbolType = SymbolType::UserDefined;
+ if (declarator->name() == "gl_Position" || declarator->name() == "gl_PointSize" ||
+ declarator->name() == "gl_ClipDistance" || declarator->name() == "gl_CullDistance")
+ {
+ symbolType = SymbolType::BuiltIn;
+ }
+ else
+ {
+ checkIsNotReserved(typeSpecifier.getLine(), declarator->name());
+ }
+ TField *field = new TField(type, declarator->name(), declarator->line(), symbolType);
+ checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *field);
+ fieldList->push_back(field);
+ }
+
+ return fieldList;
+}
+
+TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
+ const TSourceLoc &nameLine,
+ const ImmutableString &structName,
+ TFieldList *fieldList)
+{
+ SymbolType structSymbolType = SymbolType::UserDefined;
+ if (structName.empty())
+ {
+ structSymbolType = SymbolType::Empty;
+ }
+ TStructure *structure = new TStructure(&symbolTable, structName, fieldList, structSymbolType);
+
+ // Store a bool in the struct if we're at global scope, to allow us to
+ // skip the local struct scoping workaround in HLSL.
+ structure->setAtGlobalScope(symbolTable.atGlobalLevel());
+
+ if (structSymbolType != SymbolType::Empty)
+ {
+ checkIsNotReserved(nameLine, structName);
+ if (!symbolTable.declare(structure))
+ {
+ error(nameLine, "redefinition of a struct", structName);
+ }
+ }
+
+ // ensure we do not specify any storage qualifiers on the struct members
+ for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
+ {
+ TField &field = *(*fieldList)[typeListIndex];
+ const TQualifier qualifier = field.type()->getQualifier();
+ switch (qualifier)
+ {
+ case EvqGlobal:
+ case EvqTemporary:
+ break;
+ default:
+ error(field.line(), "invalid qualifier on struct member",
+ getQualifierString(qualifier));
+ break;
+ }
+ if (field.type()->isInvariant())
+ {
+ error(field.line(), "invalid qualifier on struct member", "invariant");
+ }
+ // ESSL 3.10 section 4.1.8 -- atomic_uint or images are not allowed as structure member.
+ // ANGLE_shader_pixel_local_storage also disallows PLS as struct members.
+ if (IsImage(field.type()->getBasicType()) ||
+ IsAtomicCounter(field.type()->getBasicType()) ||
+ IsPixelLocal(field.type()->getBasicType()))
+ {
+ error(field.line(), "disallowed type in struct", field.type()->getBasicString());
+ }
+
+ checkIsNotUnsizedArray(field.line(), "array members of structs must specify a size",
+ field.name(), field.type());
+
+ checkMemoryQualifierIsNotSpecified(field.type()->getMemoryQualifier(), field.line());
+
+ checkIndexIsNotSpecified(field.line(), field.type()->getLayoutQualifier().index);
+
+ checkBindingIsNotSpecified(field.line(), field.type()->getLayoutQualifier().binding);
+
+ checkLocationIsNotSpecified(field.line(), field.type()->getLayoutQualifier());
+ }
+
+ TTypeSpecifierNonArray typeSpecifierNonArray;
+ typeSpecifierNonArray.initializeStruct(structure, true, structLine);
+ exitStructDeclaration();
+
+ return typeSpecifierNonArray;
+}
+
+TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc)
+{
+ TBasicType switchType = init->getBasicType();
+ if ((switchType != EbtInt && switchType != EbtUInt) || init->isMatrix() || init->isArray() ||
+ init->isVector())
+ {
+ error(init->getLine(), "init-expression in a switch statement must be a scalar integer",
+ "switch");
+ return nullptr;
+ }
+
+ ASSERT(statementList);
+ if (!ValidateSwitchStatementList(switchType, mDiagnostics, statementList, loc))
+ {
+ ASSERT(mDiagnostics->numErrors() > 0);
+ return nullptr;
+ }
+
+ markStaticReadIfSymbol(init);
+ TIntermSwitch *node = new TIntermSwitch(init, statementList);
+ node->setLine(loc);
+ return node;
+}
+
+TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
+{
+ if (mSwitchNestingLevel == 0)
+ {
+ error(loc, "case labels need to be inside switch statements", "case");
+ return nullptr;
+ }
+ if (condition == nullptr)
+ {
+ error(loc, "case label must have a condition", "case");
+ return nullptr;
+ }
+ if ((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
+ condition->isMatrix() || condition->isArray() || condition->isVector())
+ {
+ error(condition->getLine(), "case label must be a scalar integer", "case");
+ }
+ TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
+ // ANGLE should be able to fold any EvqConst expressions resulting in an integer - but to be
+ // safe against corner cases we still check for conditionConst. Some interpretations of the
+ // spec have allowed constant expressions with side effects - like array length() method on a
+ // non-constant array.
+ if (condition->getQualifier() != EvqConst || conditionConst == nullptr)
+ {
+ error(condition->getLine(), "case label must be constant", "case");
+ }
+ TIntermCase *node = new TIntermCase(condition);
+ node->setLine(loc);
+ return node;
+}
+
+TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
+{
+ if (mSwitchNestingLevel == 0)
+ {
+ error(loc, "default labels need to be inside switch statements", "default");
+ return nullptr;
+ }
+ TIntermCase *node = new TIntermCase(nullptr);
+ node->setLine(loc);
+ return node;
+}
+
+TIntermTyped *TParseContext::createUnaryMath(TOperator op,
+ TIntermTyped *child,
+ const TSourceLoc &loc,
+ const TFunction *func)
+{
+ ASSERT(child != nullptr);
+
+ switch (op)
+ {
+ case EOpLogicalNot:
+ if (child->getBasicType() != EbtBool || child->isMatrix() || child->isArray() ||
+ child->isVector())
+ {
+ unaryOpError(loc, GetOperatorString(op), child->getType());
+ return nullptr;
+ }
+ break;
+ case EOpBitwiseNot:
+ if ((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
+ child->isMatrix() || child->isArray())
+ {
+ unaryOpError(loc, GetOperatorString(op), child->getType());
+ return nullptr;
+ }
+ break;
+ case EOpPostIncrement:
+ case EOpPreIncrement:
+ case EOpPostDecrement:
+ case EOpPreDecrement:
+ case EOpNegative:
+ case EOpPositive:
+ if (child->getBasicType() == EbtStruct || child->isInterfaceBlock() ||
+ child->getBasicType() == EbtBool || child->isArray() ||
+ child->getBasicType() == EbtVoid || IsOpaqueType(child->getBasicType()))
+ {
+ unaryOpError(loc, GetOperatorString(op), child->getType());
+ return nullptr;
+ }
+ break;
+ // Operators for math built-ins are already type checked against their prototype.
+ default:
+ break;
+ }
+
+ if (child->getMemoryQualifier().writeonly)
+ {
+ const char *opStr =
+ BuiltInGroup::IsBuiltIn(op) ? func->name().data() : GetOperatorString(op);
+ unaryOpError(loc, opStr, child->getType());
+ return nullptr;
+ }
+
+ markStaticReadIfSymbol(child);
+ TIntermUnary *node = new TIntermUnary(op, child, func);
+ node->setLine(loc);
+
+ return node->fold(mDiagnostics);
+}
+
+TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
+{
+ ASSERT(op != EOpNull);
+ TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
+ if (node == nullptr)
+ {
+ return child;
+ }
+ return node;
+}
+
+TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op,
+ TIntermTyped *child,
+ const TSourceLoc &loc)
+{
+ checkCanBeLValue(loc, GetOperatorString(op), child);
+ return addUnaryMath(op, child, loc);
+}
+
+TIntermTyped *TParseContext::expressionOrFoldedResult(TIntermTyped *expression)
+{
+ // If we can, we should return the folded version of the expression for subsequent parsing. This
+ // enables folding the containing expression during parsing as well, instead of the separate
+ // FoldExpressions() step where folding nested expressions requires multiple full AST
+ // traversals.
+
+ // Even if folding fails the fold() functions return some node representing the expression,
+ // typically the original node. So "folded" can be assumed to be non-null.
+ TIntermTyped *folded = expression->fold(mDiagnostics);
+ ASSERT(folded != nullptr);
+ if (folded->getQualifier() == expression->getQualifier())
+ {
+ // We need this expression to have the correct qualifier when validating the consuming
+ // expression. So we can only return the folded node from here in case it has the same
+ // qualifier as the original expression. In this kind of a cases the qualifier of the folded
+ // node is EvqConst, whereas the qualifier of the expression is EvqTemporary:
+ // 1. (true ? 1.0 : non_constant)
+ // 2. (non_constant, 1.0)
+ return folded;
+ }
+ return expression;
+}
+
+bool TParseContext::binaryOpCommonCheck(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ // Check opaque types are not allowed to be operands in expressions other than array indexing
+ // and structure member selection.
+ if (IsOpaqueType(left->getBasicType()) || IsOpaqueType(right->getBasicType()))
+ {
+ switch (op)
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ break;
+
+ default:
+ ASSERT(op != EOpIndexDirectStruct);
+ error(loc, "Invalid operation for variables with an opaque type",
+ GetOperatorString(op));
+ return false;
+ }
+ }
+
+ if (right->getMemoryQualifier().writeonly)
+ {
+ error(loc, "Invalid operation for variables with writeonly", GetOperatorString(op));
+ return false;
+ }
+
+ if (left->getMemoryQualifier().writeonly)
+ {
+ switch (op)
+ {
+ case EOpAssign:
+ case EOpInitialize:
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ break;
+ default:
+ error(loc, "Invalid operation for variables with writeonly", GetOperatorString(op));
+ return false;
+ }
+ }
+
+ if (left->getType().getStruct() || right->getType().getStruct())
+ {
+ switch (op)
+ {
+ case EOpIndexDirectStruct:
+ ASSERT(left->getType().getStruct());
+ break;
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpAssign:
+ case EOpInitialize:
+ if (left->getType() != right->getType())
+ {
+ return false;
+ }
+ break;
+ default:
+ error(loc, "Invalid operation for structs", GetOperatorString(op));
+ return false;
+ }
+ }
+
+ if (left->isInterfaceBlock() || right->isInterfaceBlock())
+ {
+ switch (op)
+ {
+ case EOpIndexDirectInterfaceBlock:
+ ASSERT(left->getType().getInterfaceBlock());
+ break;
+ default:
+ error(loc, "Invalid operation for interface blocks", GetOperatorString(op));
+ return false;
+ }
+ }
+
+ if (left->isArray() != right->isArray())
+ {
+ error(loc, "array / non-array mismatch", GetOperatorString(op));
+ return false;
+ }
+
+ if (left->isArray())
+ {
+ ASSERT(right->isArray());
+ if (mShaderVersion < 300)
+ {
+ error(loc, "Invalid operation for arrays", GetOperatorString(op));
+ return false;
+ }
+
+ switch (op)
+ {
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpAssign:
+ case EOpInitialize:
+ break;
+ default:
+ error(loc, "Invalid operation for arrays", GetOperatorString(op));
+ return false;
+ }
+ // At this point, size of implicitly sized arrays should be resolved.
+ if (left->getType().getArraySizes() != right->getType().getArraySizes())
+ {
+ error(loc, "array size mismatch", GetOperatorString(op));
+ return false;
+ }
+ }
+
+ // Check ops which require integer / ivec parameters
+ bool isBitShift = false;
+ switch (op)
+ {
+ case EOpBitShiftLeft:
+ case EOpBitShiftRight:
+ case EOpBitShiftLeftAssign:
+ case EOpBitShiftRightAssign:
+ // Unsigned can be bit-shifted by signed and vice versa, but we need to
+ // check that the basic type is an integer type.
+ isBitShift = true;
+ if (!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
+ {
+ return false;
+ }
+ break;
+ case EOpBitwiseAnd:
+ case EOpBitwiseXor:
+ case EOpBitwiseOr:
+ case EOpBitwiseAndAssign:
+ case EOpBitwiseXorAssign:
+ case EOpBitwiseOrAssign:
+ // It is enough to check the type of only one operand, since later it
+ // is checked that the operand types match.
+ if (!IsInteger(left->getBasicType()))
+ {
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+
+ ImplicitTypeConversion conversion = GetConversion(left->getBasicType(), right->getBasicType());
+
+ // Implicit type casting only supported for GL shaders
+ if (!isBitShift && conversion != ImplicitTypeConversion::Same &&
+ (!IsDesktopGLSpec(mShaderSpec) || !IsValidImplicitConversion(conversion, op)))
+ {
+ return false;
+ }
+
+ // Check that:
+ // 1. Type sizes match exactly on ops that require that.
+ // 2. Restrictions for structs that contain arrays or samplers are respected.
+ // 3. Arithmetic op type dimensionality restrictions for ops other than multiply are respected.
+ switch (op)
+ {
+ case EOpAssign:
+ case EOpInitialize:
+ case EOpEqual:
+ case EOpNotEqual:
+ // ESSL 1.00 sections 5.7, 5.8, 5.9
+ if (mShaderVersion < 300 && left->getType().isStructureContainingArrays())
+ {
+ error(loc, "undefined operation for structs containing arrays",
+ GetOperatorString(op));
+ return false;
+ }
+ // Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7,
+ // we interpret the spec so that this extends to structs containing samplers,
+ // similarly to ESSL 1.00 spec.
+ if ((mShaderVersion < 300 || op == EOpAssign || op == EOpInitialize) &&
+ left->getType().isStructureContainingSamplers())
+ {
+ error(loc, "undefined operation for structs containing samplers",
+ GetOperatorString(op));
+ return false;
+ }
+
+ if ((left->getNominalSize() != right->getNominalSize()) ||
+ (left->getSecondarySize() != right->getSecondarySize()))
+ {
+ error(loc, "dimension mismatch", GetOperatorString(op));
+ return false;
+ }
+ break;
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ if (!left->isScalar() || !right->isScalar())
+ {
+ error(loc, "comparison operator only defined for scalars", GetOperatorString(op));
+ return false;
+ }
+ break;
+ case EOpAdd:
+ case EOpSub:
+ case EOpDiv:
+ case EOpIMod:
+ case EOpBitShiftLeft:
+ case EOpBitShiftRight:
+ case EOpBitwiseAnd:
+ case EOpBitwiseXor:
+ case EOpBitwiseOr:
+ case EOpAddAssign:
+ case EOpSubAssign:
+ case EOpDivAssign:
+ case EOpIModAssign:
+ case EOpBitShiftLeftAssign:
+ case EOpBitShiftRightAssign:
+ case EOpBitwiseAndAssign:
+ case EOpBitwiseXorAssign:
+ case EOpBitwiseOrAssign:
+ if ((left->isMatrix() && right->isVector()) || (left->isVector() && right->isMatrix()))
+ {
+ return false;
+ }
+
+ // Are the sizes compatible?
+ if (left->getNominalSize() != right->getNominalSize() ||
+ left->getSecondarySize() != right->getSecondarySize())
+ {
+ // If the nominal sizes of operands do not match:
+ // One of them must be a scalar.
+ if (!left->isScalar() && !right->isScalar())
+ return false;
+
+ // In the case of compound assignment other than multiply-assign,
+ // the right side needs to be a scalar. Otherwise a vector/matrix
+ // would be assigned to a scalar. A scalar can't be shifted by a
+ // vector either.
+ if (!right->isScalar() &&
+ (IsAssignment(op) || op == EOpBitShiftLeft || op == EOpBitShiftRight))
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool TParseContext::isMultiplicationTypeCombinationValid(TOperator op,
+ const TType &left,
+ const TType &right)
+{
+ switch (op)
+ {
+ case EOpMul:
+ case EOpMulAssign:
+ return left.getNominalSize() == right.getNominalSize() &&
+ left.getSecondarySize() == right.getSecondarySize();
+ case EOpVectorTimesScalar:
+ return true;
+ case EOpVectorTimesScalarAssign:
+ ASSERT(!left.isMatrix() && !right.isMatrix());
+ return left.isVector() && !right.isVector();
+ case EOpVectorTimesMatrix:
+ return left.getNominalSize() == right.getRows();
+ case EOpVectorTimesMatrixAssign:
+ ASSERT(!left.isMatrix() && right.isMatrix());
+ return left.isVector() && left.getNominalSize() == right.getRows() &&
+ left.getNominalSize() == right.getCols();
+ case EOpMatrixTimesVector:
+ return left.getCols() == right.getNominalSize();
+ case EOpMatrixTimesScalar:
+ return true;
+ case EOpMatrixTimesScalarAssign:
+ ASSERT(left.isMatrix() && !right.isMatrix());
+ return !right.isVector();
+ case EOpMatrixTimesMatrix:
+ return left.getCols() == right.getRows();
+ case EOpMatrixTimesMatrixAssign:
+ ASSERT(left.isMatrix() && right.isMatrix());
+ // We need to check two things:
+ // 1. The matrix multiplication step is valid.
+ // 2. The result will have the same number of columns as the lvalue.
+ return left.getCols() == right.getRows() && left.getCols() == right.getCols();
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ if (!binaryOpCommonCheck(op, left, right, loc))
+ return nullptr;
+
+ switch (op)
+ {
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ break;
+ case EOpLogicalOr:
+ case EOpLogicalXor:
+ case EOpLogicalAnd:
+ ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
+ !right->getType().getStruct());
+ if (left->getBasicType() != EbtBool || !left->isScalar() || !right->isScalar())
+ {
+ return nullptr;
+ }
+ // Basic types matching should have been already checked.
+ ASSERT(right->getBasicType() == EbtBool);
+ break;
+ case EOpAdd:
+ case EOpSub:
+ case EOpDiv:
+ case EOpMul:
+ ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
+ !right->getType().getStruct());
+ if (left->getBasicType() == EbtBool)
+ {
+ return nullptr;
+ }
+ break;
+ case EOpIMod:
+ ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
+ !right->getType().getStruct());
+ // Note that this is only for the % operator, not for mod()
+ if (left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
+ {
+ return nullptr;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (op == EOpMul)
+ {
+ op = TIntermBinary::GetMulOpBasedOnOperands(left->getType(), right->getType());
+ if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
+ {
+ return nullptr;
+ }
+ }
+
+ TIntermBinary *node = new TIntermBinary(op, left, right);
+ ASSERT(op != EOpAssign);
+ markStaticReadIfSymbol(left);
+ markStaticReadIfSymbol(right);
+ node->setLine(loc);
+ return expressionOrFoldedResult(node);
+}
+
+TIntermTyped *TParseContext::addBinaryMath(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
+ if (node == 0)
+ {
+ binaryOpError(loc, GetOperatorString(op), left->getType(), right->getType());
+ return left;
+ }
+ return node;
+}
+
+TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
+ if (node == nullptr)
+ {
+ binaryOpError(loc, GetOperatorString(op), left->getType(), right->getType());
+ node = CreateBoolNode(false);
+ node->setLine(loc);
+ }
+ return node;
+}
+
+TIntermTyped *TParseContext::addAssign(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ checkCanBeLValue(loc, "assign", left);
+ TIntermBinary *node = nullptr;
+ if (binaryOpCommonCheck(op, left, right, loc))
+ {
+ TIntermBinary *lValue = left->getAsBinaryNode();
+ if ((lValue != nullptr) &&
+ (lValue->getOp() == EOpIndexIndirect || lValue->getOp() == EOpIndexDirect) &&
+ IsTessellationControlShaderOutput(mShaderType, lValue->getLeft()->getQualifier()))
+ {
+ checkTCSOutVarIndexIsValid(lValue, loc);
+ }
+
+ if (op == EOpMulAssign)
+ {
+ op = TIntermBinary::GetMulAssignOpBasedOnOperands(left->getType(), right->getType());
+ if (isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
+ {
+ node = new TIntermBinary(op, left, right);
+ }
+ }
+ else
+ {
+ node = new TIntermBinary(op, left, right);
+ }
+ }
+ if (node == nullptr)
+ {
+ assignError(loc, "assign", left->getType(), right->getType());
+ return left;
+ }
+ if (op != EOpAssign)
+ {
+ markStaticReadIfSymbol(left);
+ }
+ markStaticReadIfSymbol(right);
+ node->setLine(loc);
+ return node;
+}
+
+TIntermTyped *TParseContext::addComma(TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ // WebGL2 section 5.26, the following results in an error:
+ // "Sequence operator applied to void, arrays, or structs containing arrays"
+ if (mShaderSpec == SH_WEBGL2_SPEC &&
+ (left->isArray() || left->getBasicType() == EbtVoid ||
+ left->getType().isStructureContainingArrays() || right->isArray() ||
+ right->getBasicType() == EbtVoid || right->getType().isStructureContainingArrays()))
+ {
+ error(loc,
+ "sequence operator is not allowed for void, arrays, or structs containing arrays",
+ ",");
+ }
+
+ TIntermBinary *commaNode = TIntermBinary::CreateComma(left, right, mShaderVersion);
+ markStaticReadIfSymbol(left);
+ markStaticReadIfSymbol(right);
+ commaNode->setLine(loc);
+
+ return expressionOrFoldedResult(commaNode);
+}
+
+TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
+{
+ switch (op)
+ {
+ case EOpContinue:
+ if (mLoopNestingLevel <= 0)
+ {
+ error(loc, "continue statement only allowed in loops", "");
+ }
+ break;
+ case EOpBreak:
+ if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
+ {
+ error(loc, "break statement only allowed in loops and switch statements", "");
+ }
+ break;
+ case EOpReturn:
+ if (mCurrentFunctionType->getBasicType() != EbtVoid)
+ {
+ error(loc, "non-void function must return a value", "return");
+ }
+ if (mDeclaringMain)
+ {
+ errorIfPLSDeclared(loc, PLSIllegalOperations::ReturnFromMain);
+ }
+ break;
+ case EOpKill:
+ if (mShaderType != GL_FRAGMENT_SHADER)
+ {
+ error(loc, "discard supported in fragment shaders only", "discard");
+ }
+ else
+ {
+ errorIfPLSDeclared(loc, PLSIllegalOperations::Discard);
+ }
+ mHasDiscard = true;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return addBranch(op, nullptr, loc);
+}
+
+TIntermBranch *TParseContext::addBranch(TOperator op,
+ TIntermTyped *expression,
+ const TSourceLoc &loc)
+{
+ if (expression != nullptr)
+ {
+ markStaticReadIfSymbol(expression);
+ ASSERT(op == EOpReturn);
+ mFunctionReturnsValue = true;
+ if (mCurrentFunctionType->getBasicType() == EbtVoid)
+ {
+ error(loc, "void function cannot return a value", "return");
+ }
+ else if (*mCurrentFunctionType != expression->getType())
+ {
+ error(loc, "function return is not matching type:", "return");
+ }
+ }
+ TIntermBranch *node = new TIntermBranch(op, expression);
+ node->setLine(loc);
+ return node;
+}
+
+void TParseContext::appendStatement(TIntermBlock *block, TIntermNode *statement)
+{
+ if (statement != nullptr)
+ {
+ markStaticReadIfSymbol(statement);
+ block->appendStatement(statement);
+ }
+}
+
+void TParseContext::checkTextureGather(TIntermAggregate *functionCall)
+{
+ const TOperator op = functionCall->getOp();
+ const TFunction *func = functionCall->getFunction();
+ if (BuiltInGroup::IsTextureGather(op))
+ {
+ bool isTextureGatherOffsetOrOffsets =
+ BuiltInGroup::IsTextureGatherOffset(op) || BuiltInGroup::IsTextureGatherOffsets(op);
+ TIntermNode *componentNode = nullptr;
+ TIntermSequence *arguments = functionCall->getSequence();
+ ASSERT(arguments->size() >= 2u && arguments->size() <= 4u);
+ const TIntermTyped *sampler = arguments->front()->getAsTyped();
+ ASSERT(sampler != nullptr);
+ switch (sampler->getBasicType())
+ {
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ if ((!isTextureGatherOffsetOrOffsets && arguments->size() == 3u) ||
+ (isTextureGatherOffsetOrOffsets && arguments->size() == 4u))
+ {
+ componentNode = arguments->back();
+ }
+ break;
+ case EbtSamplerCube:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCubeArray:
+ case EbtISamplerCubeArray:
+ case EbtUSamplerCubeArray:
+ ASSERT(!isTextureGatherOffsetOrOffsets);
+ if (arguments->size() == 3u)
+ {
+ componentNode = arguments->back();
+ }
+ break;
+ case EbtSampler2DShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSamplerCubeArrayShadow:
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ if (componentNode)
+ {
+ const TIntermConstantUnion *componentConstantUnion =
+ componentNode->getAsConstantUnion();
+ if (componentNode->getAsTyped()->getQualifier() != EvqConst || !componentConstantUnion)
+ {
+ error(functionCall->getLine(), "Texture component must be a constant expression",
+ func->name());
+ }
+ else
+ {
+ int component = componentConstantUnion->getIConst(0);
+ if (component < 0 || component > 3)
+ {
+ error(functionCall->getLine(), "Component must be in the range [0;3]",
+ func->name());
+ }
+ }
+ }
+ }
+}
+
+void TParseContext::checkTextureOffset(TIntermAggregate *functionCall)
+{
+ const TOperator op = functionCall->getOp();
+ const TFunction *func = functionCall->getFunction();
+ TIntermNode *offset = nullptr;
+ TIntermSequence *arguments = functionCall->getSequence();
+
+ if (BuiltInGroup::IsTextureOffsetNoBias(op) || BuiltInGroup::IsTextureGatherOffsetNoComp(op) ||
+ BuiltInGroup::IsTextureGatherOffsetsNoComp(op))
+ {
+ offset = arguments->back();
+ }
+ else if (BuiltInGroup::IsTextureOffsetBias(op) || BuiltInGroup::IsTextureGatherOffsetComp(op) ||
+ BuiltInGroup::IsTextureGatherOffsetsComp(op))
+ {
+ // A bias or comp parameter follows the offset parameter.
+ ASSERT(arguments->size() >= 3);
+ offset = (*arguments)[2];
+ }
+
+ // If not one of the above built-ins, there's nothing to do here.
+ if (offset == nullptr)
+ {
+ return;
+ }
+
+ bool isTextureGatherOffset = BuiltInGroup::IsTextureGatherOffset(op);
+ bool isTextureGatherOffsets = BuiltInGroup::IsTextureGatherOffsets(op);
+ bool useTextureGatherOffsetConstraints = isTextureGatherOffset || isTextureGatherOffsets;
+
+ int minOffsetValue =
+ useTextureGatherOffsetConstraints ? mMinProgramTextureGatherOffset : mMinProgramTexelOffset;
+ int maxOffsetValue =
+ useTextureGatherOffsetConstraints ? mMaxProgramTextureGatherOffset : mMaxProgramTexelOffset;
+
+ if (isTextureGatherOffsets)
+ {
+ // If textureGatherOffsets, the offsets parameter is an array, which is expected as an
+ // aggregate constructor node or as a symbol node with a constant value.
+ TIntermAggregate *offsetAggregate = offset->getAsAggregate();
+ TIntermSymbol *offsetSymbol = offset->getAsSymbolNode();
+
+ const TConstantUnion *offsetValues = offsetAggregate ? offsetAggregate->getConstantValue()
+ : offsetSymbol ? offsetSymbol->getConstantValue()
+ : nullptr;
+
+ if (offsetValues == nullptr)
+ {
+ error(functionCall->getLine(), "Texture offsets must be a constant expression",
+ func->name());
+ return;
+ }
+
+ constexpr unsigned int kOffsetsCount = 4;
+ const TType &offsetType =
+ offsetAggregate != nullptr ? offsetAggregate->getType() : offsetSymbol->getType();
+ if (offsetType.getNumArraySizes() != 1 || offsetType.getArraySizes()[0] != kOffsetsCount)
+ {
+ error(functionCall->getLine(), "Texture offsets must be an array of 4 elements",
+ func->name());
+ return;
+ }
+
+ size_t size = offsetType.getObjectSize() / kOffsetsCount;
+ for (unsigned int i = 0; i < kOffsetsCount; ++i)
+ {
+ checkSingleTextureOffset(offset->getLine(), &offsetValues[i * size], size,
+ minOffsetValue, maxOffsetValue);
+ }
+ }
+ else
+ {
+ // If textureOffset or textureGatherOffset, the offset is expected to be found as a constant
+ // union.
+ TIntermConstantUnion *offsetConstantUnion = offset->getAsConstantUnion();
+
+ // ES3.2 or ES3.1's EXT_gpu_shader5 allow non-const offsets to be passed to
+ // textureGatherOffset.
+ bool textureGatherOffsetMustBeConst =
+ mShaderVersion <= 310 && !isExtensionEnabled(TExtension::EXT_gpu_shader5);
+
+ bool isOffsetConst =
+ offset->getAsTyped()->getQualifier() == EvqConst && offsetConstantUnion != nullptr;
+ bool offsetMustBeConst = !isTextureGatherOffset || textureGatherOffsetMustBeConst;
+
+ if (!isOffsetConst && offsetMustBeConst)
+ {
+ error(functionCall->getLine(), "Texture offset must be a constant expression",
+ func->name());
+ return;
+ }
+
+ // We cannot verify non-constant offsets to textureGatherOffset.
+ if (offsetConstantUnion == nullptr)
+ {
+ ASSERT(!offsetMustBeConst);
+ return;
+ }
+
+ size_t size = offsetConstantUnion->getType().getObjectSize();
+ const TConstantUnion *values = offsetConstantUnion->getConstantValue();
+ checkSingleTextureOffset(offset->getLine(), values, size, minOffsetValue, maxOffsetValue);
+ }
+}
+
+void TParseContext::checkSingleTextureOffset(const TSourceLoc &line,
+ const TConstantUnion *values,
+ size_t size,
+ int minOffsetValue,
+ int maxOffsetValue)
+{
+ for (size_t i = 0u; i < size; ++i)
+ {
+ ASSERT(values[i].getType() == EbtInt);
+ int offsetValue = values[i].getIConst();
+ if (offsetValue > maxOffsetValue || offsetValue < minOffsetValue)
+ {
+ std::stringstream tokenStream = sh::InitializeStream<std::stringstream>();
+ tokenStream << offsetValue;
+ std::string token = tokenStream.str();
+ error(line, "Texture offset value out of valid range", token.c_str());
+ }
+ }
+}
+
+void TParseContext::checkInterpolationFS(TIntermAggregate *functionCall)
+{
+ const TFunction *func = functionCall->getFunction();
+ if (!BuiltInGroup::IsInterpolationFS(functionCall->getOp()))
+ {
+ return;
+ }
+
+ TIntermTyped *arg0 = nullptr;
+
+ if (functionCall->getAsAggregate())
+ {
+ const TIntermSequence *argp = functionCall->getSequence();
+ if (argp->size() > 0)
+ arg0 = (*argp)[0]->getAsTyped();
+ }
+ else
+ {
+ assert(functionCall->getAsUnaryNode());
+ arg0 = functionCall->getAsUnaryNode()->getOperand();
+ }
+
+ // Make sure the first argument is an interpolant, or an array element of an interpolant
+ if (!IsVaryingIn(arg0->getType().getQualifier()))
+ {
+ // It might still be an array element.
+ const TIntermTyped *base = FindLValueBase(arg0);
+
+ if (base == nullptr || (!IsVaryingIn(base->getType().getQualifier())))
+ error(arg0->getLine(),
+ "first argument must be an interpolant, or interpolant-array element",
+ func->name());
+ }
+}
+
+void TParseContext::checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall)
+{
+ const TFunction *func = functionCall->getFunction();
+ if (BuiltInGroup::IsAtomicMemory(functionCall->getOp()))
+ {
+ TIntermSequence *arguments = functionCall->getSequence();
+ TIntermTyped *memNode = (*arguments)[0]->getAsTyped();
+
+ if (IsBufferOrSharedVariable(memNode))
+ {
+ return;
+ }
+
+ while (memNode->getAsBinaryNode() || memNode->getAsSwizzleNode())
+ {
+ // Child 0 is "left" if binary, and the expression being swizzled if swizzle.
+ // Note: we don't need to check that the binary operation is one of EOp*Index*, as any
+ // other operation will result in a temp value which cannot be passed to this
+ // out/inout parameter anyway.
+ memNode = memNode->getChildNode(0)->getAsTyped();
+ if (IsBufferOrSharedVariable(memNode))
+ {
+ return;
+ }
+ }
+
+ error(memNode->getLine(),
+ "The value passed to the mem argument of an atomic memory function does not "
+ "correspond to a buffer or shared variable.",
+ func->name());
+ }
+}
+
+// GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
+void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall)
+{
+ const TOperator op = functionCall->getOp();
+
+ if (BuiltInGroup::IsImage(op))
+ {
+ TIntermSequence *arguments = functionCall->getSequence();
+ TIntermTyped *imageNode = (*arguments)[0]->getAsTyped();
+
+ const TMemoryQualifier &memoryQualifier = imageNode->getMemoryQualifier();
+
+ if (BuiltInGroup::IsImageStore(op))
+ {
+ if (memoryQualifier.readonly)
+ {
+ error(imageNode->getLine(),
+ "'imageStore' cannot be used with images qualified as 'readonly'",
+ GetImageArgumentToken(imageNode));
+ }
+ }
+ else if (BuiltInGroup::IsImageLoad(op))
+ {
+ if (memoryQualifier.writeonly)
+ {
+ error(imageNode->getLine(),
+ "'imageLoad' cannot be used with images qualified as 'writeonly'",
+ GetImageArgumentToken(imageNode));
+ }
+ }
+ else if (BuiltInGroup::IsImageAtomic(op))
+ {
+ if (memoryQualifier.readonly)
+ {
+ error(imageNode->getLine(),
+ "'imageAtomic' cannot be used with images qualified as 'readonly'",
+ GetImageArgumentToken(imageNode));
+ }
+ if (memoryQualifier.writeonly)
+ {
+ error(imageNode->getLine(),
+ "'imageAtomic' cannot be used with images qualified as 'writeonly'",
+ GetImageArgumentToken(imageNode));
+ }
+ }
+ }
+}
+
+// GLSL ES 3.10 Revision 4, 13.51 Matching of Memory Qualifiers in Function Parameters
+void TParseContext::checkImageMemoryAccessForUserDefinedFunctions(
+ const TFunction *functionDefinition,
+ const TIntermAggregate *functionCall)
+{
+ ASSERT(functionCall->getOp() == EOpCallFunctionInAST);
+
+ const TIntermSequence &arguments = *functionCall->getSequence();
+
+ ASSERT(functionDefinition->getParamCount() == arguments.size());
+
+ for (size_t i = 0; i < arguments.size(); ++i)
+ {
+ TIntermTyped *typedArgument = arguments[i]->getAsTyped();
+ const TType &functionArgumentType = typedArgument->getType();
+ const TType &functionParameterType = functionDefinition->getParam(i)->getType();
+ ASSERT(functionArgumentType.getBasicType() == functionParameterType.getBasicType());
+
+ if (IsImage(functionArgumentType.getBasicType()))
+ {
+ const TMemoryQualifier &functionArgumentMemoryQualifier =
+ functionArgumentType.getMemoryQualifier();
+ const TMemoryQualifier &functionParameterMemoryQualifier =
+ functionParameterType.getMemoryQualifier();
+ if (functionArgumentMemoryQualifier.readonly &&
+ !functionParameterMemoryQualifier.readonly)
+ {
+ error(functionCall->getLine(),
+ "Function call discards the 'readonly' qualifier from image",
+ GetImageArgumentToken(typedArgument));
+ }
+
+ if (functionArgumentMemoryQualifier.writeonly &&
+ !functionParameterMemoryQualifier.writeonly)
+ {
+ error(functionCall->getLine(),
+ "Function call discards the 'writeonly' qualifier from image",
+ GetImageArgumentToken(typedArgument));
+ }
+
+ if (functionArgumentMemoryQualifier.coherent &&
+ !functionParameterMemoryQualifier.coherent)
+ {
+ error(functionCall->getLine(),
+ "Function call discards the 'coherent' qualifier from image",
+ GetImageArgumentToken(typedArgument));
+ }
+
+ if (functionArgumentMemoryQualifier.volatileQualifier &&
+ !functionParameterMemoryQualifier.volatileQualifier)
+ {
+ error(functionCall->getLine(),
+ "Function call discards the 'volatile' qualifier from image",
+ GetImageArgumentToken(typedArgument));
+ }
+ }
+ }
+}
+
+TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunctionLookup *fnCall, const TSourceLoc &loc)
+{
+ if (fnCall->thisNode() != nullptr)
+ {
+ return addMethod(fnCall, loc);
+ }
+ if (fnCall->isConstructor())
+ {
+ return addConstructor(fnCall, loc);
+ }
+ return addNonConstructorFunctionCall(fnCall, loc);
+}
+
+TIntermTyped *TParseContext::addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc)
+{
+ TIntermTyped *thisNode = fnCall->thisNode();
+ // It's possible for the name pointer in the TFunction to be null in case it gets parsed as
+ // a constructor. But such a TFunction can't reach here, since the lexer goes into FIELDS
+ // mode after a dot, which makes type identifiers to be parsed as FIELD_SELECTION instead.
+ // So accessing fnCall->name() below is safe.
+ if (fnCall->name() != "length")
+ {
+ error(loc, "invalid method", fnCall->name());
+ }
+ else if (!fnCall->arguments().empty())
+ {
+ error(loc, "method takes no parameters", "length");
+ }
+ else if (!thisNode->isArray())
+ {
+ error(loc, "length can only be called on arrays", "length");
+ }
+ else if (thisNode->getQualifier() == EvqPerVertexIn &&
+ mGeometryShaderInputPrimitiveType == EptUndefined)
+ {
+ ASSERT(mShaderType == GL_GEOMETRY_SHADER_EXT);
+ error(loc, "missing input primitive declaration before calling length on gl_in", "length");
+ }
+ else
+ {
+ TIntermUnary *node = new TIntermUnary(EOpArrayLength, thisNode, nullptr);
+ markStaticReadIfSymbol(thisNode);
+ node->setLine(loc);
+ return node->fold(mDiagnostics);
+ }
+ return CreateZeroNode(TType(EbtInt, EbpUndefined, EvqConst));
+}
+
+TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunctionLookup *fnCall,
+ const TSourceLoc &loc)
+{
+ // First check whether the function has been hidden by a variable name or struct typename by
+ // using the symbol looked up in the lexical phase. If the function is not hidden, look for one
+ // with a matching argument list.
+ if (fnCall->symbol() != nullptr && !fnCall->symbol()->isFunction())
+ {
+ error(loc, "function name expected", fnCall->name());
+ }
+ else
+ {
+ // There are no inner functions, so it's enough to look for user-defined functions in the
+ // global scope.
+ const TSymbol *symbol = symbolTable.findGlobal(fnCall->getMangledName());
+
+ if (symbol == nullptr && IsDesktopGLSpec(mShaderSpec))
+ {
+ // If using Desktop GL spec, need to check for implicit conversion
+ symbol = symbolTable.findGlobalWithConversion(
+ fnCall->getMangledNamesForImplicitConversions());
+ }
+
+ if (symbol != nullptr)
+ {
+ // A user-defined function - could be an overloaded built-in as well.
+ ASSERT(symbol->symbolType() == SymbolType::UserDefined);
+ const TFunction *fnCandidate = static_cast<const TFunction *>(symbol);
+ TIntermAggregate *callNode =
+ TIntermAggregate::CreateFunctionCall(*fnCandidate, &fnCall->arguments());
+ callNode->setLine(loc);
+ checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, callNode);
+ functionCallRValueLValueErrorCheck(fnCandidate, callNode);
+ return callNode;
+ }
+
+ symbol = symbolTable.findBuiltIn(fnCall->getMangledName(), mShaderVersion);
+
+ if (symbol == nullptr && IsDesktopGLSpec(mShaderSpec))
+ {
+ // If using Desktop GL spec, need to check for implicit conversion
+ symbol = symbolTable.findBuiltInWithConversion(
+ fnCall->getMangledNamesForImplicitConversions(), mShaderVersion);
+ }
+
+ if (symbol != nullptr)
+ {
+ // A built-in function.
+ ASSERT(symbol->symbolType() == SymbolType::BuiltIn);
+ const TFunction *fnCandidate = static_cast<const TFunction *>(symbol);
+
+ if (!fnCandidate->extensions().empty() &&
+ fnCandidate->extensions()[0] != TExtension::UNDEFINED)
+ {
+ checkCanUseOneOfExtensions(loc, fnCandidate->extensions());
+ }
+
+ // All function calls are mapped to a built-in operation.
+ TOperator op = fnCandidate->getBuiltInOp();
+ if (BuiltInGroup::IsMath(op) && fnCandidate->getParamCount() == 1)
+ {
+ // Treat it like a built-in unary operator.
+ TIntermNode *unaryParamNode = fnCall->arguments().front();
+ TIntermTyped *callNode =
+ createUnaryMath(op, unaryParamNode->getAsTyped(), loc, fnCandidate);
+ ASSERT(callNode != nullptr);
+ return callNode;
+ }
+
+ TIntermAggregate *callNode =
+ TIntermAggregate::CreateBuiltInFunctionCall(*fnCandidate, &fnCall->arguments());
+ callNode->setLine(loc);
+
+ checkAtomicMemoryBuiltinFunctions(callNode);
+ checkTextureOffset(callNode);
+ checkTextureGather(callNode);
+ checkInterpolationFS(callNode);
+ checkImageMemoryAccessForBuiltinFunctions(callNode);
+
+ // Some built-in functions have out parameters too.
+ functionCallRValueLValueErrorCheck(fnCandidate, callNode);
+
+ // See if we can constant fold a built-in. Note that this may be possible
+ // even if it is not const-qualified.
+ return callNode->fold(mDiagnostics);
+ }
+ else
+ {
+ error(loc, "no matching overloaded function found", fnCall->name());
+ }
+ }
+
+ // Error message was already written. Put on an unused node for error recovery.
+ return CreateZeroNode(TType(EbtFloat, EbpMedium, EvqConst));
+}
+
+TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
+ TIntermTyped *trueExpression,
+ TIntermTyped *falseExpression,
+ const TSourceLoc &loc)
+{
+ if (!checkIsScalarBool(loc, cond))
+ {
+ return falseExpression;
+ }
+
+ if (trueExpression->getType() != falseExpression->getType())
+ {
+ TInfoSinkBase reasonStream;
+ reasonStream << "mismatching ternary operator operand types '" << trueExpression->getType()
+ << " and '" << falseExpression->getType() << "'";
+ error(loc, reasonStream.c_str(), "?:");
+ return falseExpression;
+ }
+ if (IsOpaqueType(trueExpression->getBasicType()))
+ {
+ // ESSL 1.00 section 4.1.7
+ // ESSL 3.00.6 section 4.1.7
+ // Opaque/sampler types are not allowed in most types of expressions, including ternary.
+ // Note that structs containing opaque types don't need to be checked as structs are
+ // forbidden below.
+ error(loc, "ternary operator is not allowed for opaque types", "?:");
+ return falseExpression;
+ }
+
+ if (cond->getMemoryQualifier().writeonly || trueExpression->getMemoryQualifier().writeonly ||
+ falseExpression->getMemoryQualifier().writeonly)
+ {
+ error(loc, "ternary operator is not allowed for variables with writeonly", "?:");
+ return falseExpression;
+ }
+
+ // ESSL 1.00.17 sections 5.2 and 5.7:
+ // Ternary operator is not among the operators allowed for structures/arrays.
+ // ESSL 3.00.6 section 5.7:
+ // Ternary operator support is optional for arrays. No certainty that it works across all
+ // devices with struct either, so we err on the side of caution here. TODO (oetuaho@nvidia.com):
+ // Would be nice to make the spec and implementation agree completely here.
+ if (trueExpression->isArray() || trueExpression->getBasicType() == EbtStruct)
+ {
+ error(loc, "ternary operator is not allowed for structures or arrays", "?:");
+ return falseExpression;
+ }
+ if (trueExpression->getBasicType() == EbtInterfaceBlock)
+ {
+ error(loc, "ternary operator is not allowed for interface blocks", "?:");
+ return falseExpression;
+ }
+
+ // WebGL2 section 5.26, the following results in an error:
+ // "Ternary operator applied to void, arrays, or structs containing arrays"
+ if (mShaderSpec == SH_WEBGL2_SPEC && trueExpression->getBasicType() == EbtVoid)
+ {
+ error(loc, "ternary operator is not allowed for void", "?:");
+ return falseExpression;
+ }
+
+ TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression);
+ markStaticReadIfSymbol(cond);
+ markStaticReadIfSymbol(trueExpression);
+ markStaticReadIfSymbol(falseExpression);
+ node->setLine(loc);
+ return expressionOrFoldedResult(node);
+}
+
+//
+// Parse an array of strings using yyparse.
+//
+// Returns 0 for success.
+//
+int PaParseStrings(size_t count,
+ const char *const string[],
+ const int length[],
+ TParseContext *context)
+{
+ if ((count == 0) || (string == nullptr))
+ return 1;
+
+ if (glslang_initialize(context))
+ return 1;
+
+ int error = glslang_scan(count, string, length, context);
+ if (!error)
+ error = glslang_parse(context);
+
+ glslang_finalize(context);
+
+ return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ParseContext.h b/gfx/angle/checkout/src/compiler/translator/ParseContext.h
new file mode 100644
index 0000000000..666f5e3851
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ParseContext.h
@@ -0,0 +1,818 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+#ifndef COMPILER_TRANSLATOR_PARSECONTEXT_H_
+#define COMPILER_TRANSLATOR_PARSECONTEXT_H_
+
+#include "compiler/preprocessor/Preprocessor.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/Declarator.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/DirectiveHandler.h"
+#include "compiler/translator/FunctionLookup.h"
+#include "compiler/translator/QualifierTypes.h"
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+struct TMatrixFields
+{
+ bool wholeRow;
+ bool wholeCol;
+ int row;
+ int col;
+};
+
+//
+// The following are extra variables needed during parsing, grouped together so
+// they can be passed to the parser without needing a global.
+//
+class TParseContext : angle::NonCopyable
+{
+ public:
+ TParseContext(TSymbolTable &symt,
+ TExtensionBehavior &ext,
+ sh::GLenum type,
+ ShShaderSpec spec,
+ const ShCompileOptions &options,
+ bool checksPrecErrors,
+ TDiagnostics *diagnostics,
+ const ShBuiltInResources &resources,
+ ShShaderOutput outputType);
+ ~TParseContext();
+
+ bool anyMultiviewExtensionAvailable();
+ const angle::pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
+ angle::pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
+ void *getScanner() const { return mScanner; }
+ void setScanner(void *scanner) { mScanner = scanner; }
+ int getShaderVersion() const { return mShaderVersion; }
+ sh::GLenum getShaderType() const { return mShaderType; }
+ ShShaderSpec getShaderSpec() const { return mShaderSpec; }
+ int numErrors() const { return mDiagnostics->numErrors(); }
+ void error(const TSourceLoc &loc, const char *reason, const char *token);
+ void error(const TSourceLoc &loc, const char *reason, const ImmutableString &token);
+ void warning(const TSourceLoc &loc, const char *reason, const char *token);
+
+ // If isError is false, a warning will be reported instead.
+ void outOfRangeError(bool isError,
+ const TSourceLoc &loc,
+ const char *reason,
+ const char *token);
+
+ TIntermBlock *getTreeRoot() const { return mTreeRoot; }
+ void setTreeRoot(TIntermBlock *treeRoot);
+
+ bool getFragmentPrecisionHigh() const
+ {
+ return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300;
+ }
+ void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)
+ {
+ mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
+ }
+
+ bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
+ bool hasDiscard() const { return mHasDiscard; }
+ bool isSampleQualifierSpecified() const { return mSampleQualifierSpecified; }
+
+ void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; }
+
+ void incrLoopNestingLevel() { ++mLoopNestingLevel; }
+ void decrLoopNestingLevel() { --mLoopNestingLevel; }
+
+ void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
+ void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
+
+ bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
+ sh::WorkGroupSize getComputeShaderLocalSize() const;
+
+ int getNumViews() const { return mNumViews; }
+
+ const std::map<int, TLayoutImageInternalFormat> &pixelLocalStorageBindings() const
+ {
+ return mPLSBindings;
+ }
+
+ void enterFunctionDeclaration() { mDeclaringFunction = true; }
+
+ void exitFunctionDeclaration() { mDeclaringFunction = false; }
+
+ bool declaringFunction() const { return mDeclaringFunction; }
+
+ TIntermConstantUnion *addScalarLiteral(const TConstantUnion *constantUnion,
+ const TSourceLoc &line);
+
+ // This method is guaranteed to succeed, even if no variable with 'name' exists.
+ const TVariable *getNamedVariable(const TSourceLoc &location,
+ const ImmutableString &name,
+ const TSymbol *symbol);
+ TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
+ const ImmutableString &name,
+ const TSymbol *symbol);
+
+ // Look at a '.' field selector string and change it into offsets for a vector.
+ bool parseVectorFields(const TSourceLoc &line,
+ const ImmutableString &compString,
+ int vecSize,
+ TVector<int> *fieldOffsets);
+
+ void assignError(const TSourceLoc &line, const char *op, const TType &left, const TType &right);
+ void unaryOpError(const TSourceLoc &line, const char *op, const TType &operand);
+ void binaryOpError(const TSourceLoc &line,
+ const char *op,
+ const TType &left,
+ const TType &right);
+
+ // Check functions - the ones that return bool return false if an error was generated.
+
+ bool checkIsNotReserved(const TSourceLoc &line, const ImmutableString &identifier);
+ void checkPrecisionSpecified(const TSourceLoc &line, TPrecision precision, TBasicType type);
+ bool checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node);
+ void checkIsConst(TIntermTyped *node);
+ void checkIsScalarInteger(TIntermTyped *node, const char *token);
+ bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token);
+ bool checkConstructorArguments(const TSourceLoc &line,
+ const TIntermSequence &arguments,
+ const TType &type);
+
+ // Returns a sanitized array size to use (the size is at least 1).
+ unsigned int checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr);
+ bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier);
+ bool checkArrayElementIsNotArray(const TSourceLoc &line, const TPublicType &elementType);
+ bool checkArrayOfArraysInOut(const TSourceLoc &line,
+ const TPublicType &elementType,
+ const TType &arrayType);
+ bool checkIsNonVoid(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const TBasicType &type);
+ bool checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type);
+ void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType);
+ bool checkIsNotOpaqueType(const TSourceLoc &line,
+ const TTypeSpecifierNonArray &pType,
+ const char *reason);
+ void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType);
+ void checkLocationIsNotSpecified(const TSourceLoc &location,
+ const TLayoutQualifier &layoutQualifier);
+ void checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
+ const TLayoutBlockStorage &blockStorage,
+ const TQualifier &qualifier);
+ void checkIsParameterQualifierValid(const TSourceLoc &line,
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ TType *type);
+
+ // Check if at least one of the specified extensions can be used, and generate error/warning as
+ // appropriate according to the spec.
+ // This function is only needed for a few different small constant sizes of extension array, and
+ // we want to avoid unnecessary dynamic allocations. That's why checkCanUseOneOfExtensions is a
+ // template function rather than one taking a vector.
+ template <size_t size>
+ bool checkCanUseOneOfExtensions(const TSourceLoc &line,
+ const std::array<TExtension, size> &extensions);
+ bool checkCanUseExtension(const TSourceLoc &line, TExtension extension);
+
+ // Done for all declarations, whether empty or not.
+ void declarationQualifierErrorCheck(const sh::TQualifier qualifier,
+ const sh::TLayoutQualifier &layoutQualifier,
+ const TSourceLoc &location);
+ // Done for the first non-empty declarator in a declaration.
+ void nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation);
+ // Done only for empty declarations.
+ void emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location);
+
+ void checkCanUseLayoutQualifier(const TSourceLoc &location);
+ bool checkLayoutQualifierSupported(const TSourceLoc &location,
+ const ImmutableString &layoutQualifierName,
+ int versionRequired);
+ bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
+ const TLayoutQualifier &layoutQualifier);
+ void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
+ void checkInvariantVariableQualifier(bool invariant,
+ const TQualifier qualifier,
+ const TSourceLoc &invariantLocation);
+ void checkInputOutputTypeIsValidES3(const TQualifier qualifier,
+ const TPublicType &type,
+ const TSourceLoc &qualifierLocation);
+ void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier);
+ void checkTCSOutVarIndexIsValid(TIntermBinary *binaryExpression, const TSourceLoc &location);
+
+ void checkAdvancedBlendEquationsNotSpecified(
+ const TSourceLoc &location,
+ const AdvancedBlendEquations &advancedBlendEquations,
+ const TQualifier &qualifier);
+
+ const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
+ const TExtensionBehavior &extensionBehavior() const
+ {
+ return mDirectiveHandler.extensionBehavior();
+ }
+
+ bool isExtensionEnabled(TExtension extension) const;
+ void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
+ void handlePragmaDirective(const TSourceLoc &loc,
+ const char *name,
+ const char *value,
+ bool stdgl);
+
+ // For built-ins that can be redeclared, adjusts the type qualifier so transformations can
+ // identify them correctly.
+ void adjustRedeclaredBuiltInType(const ImmutableString &identifier, TType *type);
+
+ // Returns true on success. *initNode may still be nullptr on success in case the initialization
+ // is not needed in the AST.
+ bool executeInitializer(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ TType *type,
+ TIntermTyped *initializer,
+ TIntermBinary **initNode);
+ TIntermNode *addConditionInitializer(const TPublicType &pType,
+ const ImmutableString &identifier,
+ TIntermTyped *initializer,
+ const TSourceLoc &loc);
+ TIntermNode *addLoop(TLoopType type,
+ TIntermNode *init,
+ TIntermNode *cond,
+ TIntermTyped *expr,
+ TIntermNode *body,
+ const TSourceLoc &loc);
+
+ // For "if" test nodes. There are three children: a condition, a true path, and a false path.
+ // The two paths are in TIntermNodePair code.
+ TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc);
+
+ void addFullySpecifiedType(TPublicType *typeSpecifier);
+ TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TPublicType &typeSpecifier);
+
+ TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierOrTypeLocation,
+ const ImmutableString &identifier);
+ TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes);
+ TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer);
+
+ // Parse a declaration like "type a[n] = initializer"
+ // Note that this does not apply to declarations like "type[n] a = initializer"
+ TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer);
+
+ TIntermGlobalQualifierDeclaration *parseGlobalQualifierDeclaration(
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TSourceLoc &identifierLoc,
+ const ImmutableString &identifier,
+ const TSymbol *symbol);
+
+ void parseDeclarator(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ TIntermDeclaration *declarationOut);
+ void parseArrayDeclarator(TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &arrayLocation,
+ const TVector<unsigned int> &arraySizes,
+ TIntermDeclaration *declarationOut);
+ void parseInitDeclarator(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut);
+
+ // Parse a declarator like "a[n] = initializer"
+ void parseArrayInitDeclarator(const TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut);
+
+ TIntermNode *addEmptyStatement(const TSourceLoc &location);
+
+ void parseDefaultPrecisionQualifier(const TPrecision precision,
+ const TPublicType &type,
+ const TSourceLoc &loc);
+ void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
+
+ TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
+ const TSourceLoc &location);
+ TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype,
+ TIntermBlock *functionBody,
+ const TSourceLoc &location);
+ void parseFunctionDefinitionHeader(const TSourceLoc &location,
+ const TFunction *function,
+ TIntermFunctionPrototype **prototypeOut);
+ TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function);
+ TFunction *parseFunctionHeader(const TPublicType &type,
+ const ImmutableString &name,
+ const TSourceLoc &location);
+
+ TFunctionLookup *addNonConstructorFunc(const ImmutableString &name, const TSymbol *symbol);
+ TFunctionLookup *addConstructorFunc(const TPublicType &publicType);
+
+ TParameter parseParameterDeclarator(const TPublicType &publicType,
+ const ImmutableString &name,
+ const TSourceLoc &nameLoc);
+
+ TParameter parseParameterArrayDeclarator(const ImmutableString &name,
+ const TSourceLoc &nameLoc,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &arrayLoc,
+ TPublicType *elementType);
+
+ TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
+ const TSourceLoc &location,
+ TIntermTyped *indexExpression);
+ TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression,
+ const TSourceLoc &dotLocation,
+ const ImmutableString &fieldString,
+ const TSourceLoc &fieldLocation);
+
+ // Parse declarator for a single field
+ TDeclarator *parseStructDeclarator(const ImmutableString &identifier, const TSourceLoc &loc);
+ TDeclarator *parseStructArrayDeclarator(const ImmutableString &identifier,
+ const TSourceLoc &loc,
+ const TVector<unsigned int> *arraySizes);
+
+ void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
+ const TFieldList::const_iterator end,
+ const ImmutableString &name,
+ const TSourceLoc &location);
+ TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
+ TFieldList *combineStructFieldLists(TFieldList *processedFields,
+ const TFieldList *newlyAddedFields,
+ const TSourceLoc &location);
+ TFieldList *addStructDeclaratorListWithQualifiers(
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ TPublicType *typeSpecifier,
+ const TDeclaratorList *declaratorList);
+ TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier,
+ const TDeclaratorList *declaratorList);
+ TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
+ const TSourceLoc &nameLine,
+ const ImmutableString &structName,
+ TFieldList *fieldList);
+
+ TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TSourceLoc &nameLine,
+ const ImmutableString &blockName,
+ TFieldList *fieldList,
+ const ImmutableString &instanceName,
+ const TSourceLoc &instanceLine,
+ const TVector<unsigned int> *arraySizes,
+ const TSourceLoc &arraySizesLine);
+
+ void parseLocalSize(const ImmutableString &qualifierType,
+ const TSourceLoc &qualifierTypeLine,
+ int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ size_t index,
+ sh::WorkGroupSize *localSize);
+ void parseNumViews(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numViews);
+ void parseInvocations(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numInvocations);
+ void parseMaxVertices(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numMaxVertices);
+ void parseVertices(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numVertices);
+ void parseIndexLayoutQualifier(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *index);
+ TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
+ const TSourceLoc &qualifierTypeLine);
+ TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
+ const TSourceLoc &qualifierTypeLine,
+ int intValue,
+ const TSourceLoc &intValueLine);
+ TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc);
+ TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier,
+ const TSourceLoc &loc);
+ TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc);
+ TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc);
+ TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc);
+ TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc);
+ TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
+ TLayoutQualifier rightQualifier,
+ const TSourceLoc &rightQualifierLocation);
+
+ // Performs an error check for embedded struct declarations.
+ void enterStructDeclaration(const TSourceLoc &line, const ImmutableString &identifier);
+ void exitStructDeclaration();
+
+ void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
+
+ TIntermSwitch *addSwitch(TIntermTyped *init,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc);
+ TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
+ TIntermCase *addDefault(const TSourceLoc &loc);
+
+ TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
+ TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
+ TIntermTyped *addBinaryMath(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc);
+ TIntermTyped *addBinaryMathBooleanResult(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc);
+ TIntermTyped *addAssign(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc);
+
+ TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
+
+ TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
+ TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc);
+
+ void appendStatement(TIntermBlock *block, TIntermNode *statement);
+
+ void checkTextureGather(TIntermAggregate *functionCall);
+ void checkTextureOffset(TIntermAggregate *functionCall);
+ void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
+ void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
+ const TIntermAggregate *functionCall);
+ void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall);
+ void checkInterpolationFS(TIntermAggregate *functionCall);
+
+ // fnCall is only storing the built-in op, and function name or constructor type. arguments
+ // has the arguments.
+ TIntermTyped *addFunctionCallOrMethod(TFunctionLookup *fnCall, const TSourceLoc &loc);
+
+ TIntermTyped *addTernarySelection(TIntermTyped *cond,
+ TIntermTyped *trueExpression,
+ TIntermTyped *falseExpression,
+ const TSourceLoc &line);
+
+ int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
+ int getGeometryShaderInvocations() const
+ {
+ return (mGeometryShaderInvocations > 0) ? mGeometryShaderInvocations : 1;
+ }
+ TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
+ {
+ return mGeometryShaderInputPrimitiveType;
+ }
+ TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
+ {
+ return mGeometryShaderOutputPrimitiveType;
+ }
+ int getTessControlShaderOutputVertices() const { return mTessControlShaderOutputVertices; }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputPrimitiveType() const
+ {
+ return mTessEvaluationShaderInputPrimitiveType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputVertexSpacingType() const
+ {
+ return mTessEvaluationShaderInputVertexSpacingType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputOrderingType() const
+ {
+ return mTessEvaluationShaderInputOrderingType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputPointType() const
+ {
+ return mTessEvaluationShaderInputPointType;
+ }
+
+ const TVector<TType *> &getDeferredArrayTypesToSize() const
+ {
+ return mDeferredArrayTypesToSize;
+ }
+
+ void markShaderHasPrecise() { mHasAnyPreciseType = true; }
+ bool hasAnyPreciseType() const { return mHasAnyPreciseType; }
+ AdvancedBlendEquations getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
+
+ ShShaderOutput getOutputType() const { return mOutputType; }
+
+ // TODO(jmadill): make this private
+ TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed
+
+ private:
+ class AtomicCounterBindingState;
+ constexpr static size_t kAtomicCounterSize = 4;
+ // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which
+ // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is
+ // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently
+ // we treat it as always 4 in favour of the original interpretation in
+ // "ARB_shader_atomic_counters".
+ // TODO(jie.a.chen@intel.com): Double check this once the spec vagueness is resolved.
+ // Note that there may be tests in AtomicCounter_test that will need to be updated as well.
+ constexpr static size_t kAtomicCounterArrayStride = 4;
+
+ void markStaticReadIfSymbol(TIntermNode *node);
+
+ // Returns a clamped index. If it prints out an error message, the token is "[]".
+ int checkIndexLessThan(bool outOfRangeIndexIsError,
+ const TSourceLoc &location,
+ int index,
+ int arraySize,
+ const char *reason);
+
+ bool declareVariable(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const TType *type,
+ TVariable **variable);
+
+ void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ TType *type);
+
+ TParameter parseParameterDeclarator(TType *type,
+ const ImmutableString &name,
+ const TSourceLoc &nameLoc);
+
+ bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
+ const TPublicType &elementType);
+ // Done for all atomic counter declarations, whether empty or not.
+ void atomicCounterQualifierErrorCheck(const TPublicType &publicType,
+ const TSourceLoc &location);
+
+ // Assumes that multiplication op has already been set based on the types.
+ bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right);
+
+ void checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
+ TQualifier qualifier,
+ const TType &type);
+
+ void checkInternalFormatIsNotSpecified(const TSourceLoc &location,
+ TLayoutImageInternalFormat internalFormat);
+ void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
+ const TSourceLoc &location);
+ void checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
+ const TSourceLoc &loc,
+ TType *type);
+ void checkAtomicCounterOffsetAlignment(const TSourceLoc &location, const TType &type);
+
+ void checkIndexIsNotSpecified(const TSourceLoc &location, int index);
+ void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type);
+ void checkBindingIsNotSpecified(const TSourceLoc &location, int binding);
+ void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset);
+ void checkImageBindingIsValid(const TSourceLoc &location,
+ int binding,
+ int arrayTotalElementCount);
+ void checkSamplerBindingIsValid(const TSourceLoc &location,
+ int binding,
+ int arrayTotalElementCount);
+ void checkBlockBindingIsValid(const TSourceLoc &location,
+ const TQualifier &qualifier,
+ int binding,
+ int arraySize);
+ void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding);
+ void checkPixelLocalStorageBindingIsValid(const TSourceLoc &, const TType &);
+
+ void checkUniformLocationInRange(const TSourceLoc &location,
+ int objectLocationCount,
+ const TLayoutQualifier &layoutQualifier);
+ void checkAttributeLocationInRange(const TSourceLoc &location,
+ int objectLocationCount,
+ const TLayoutQualifier &layoutQualifier);
+
+ void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv);
+
+ void checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc &location, bool earlyFragmentTests);
+
+ void checkNoncoherentIsSpecified(const TSourceLoc &location, bool noncoherent);
+
+ void checkNoncoherentIsNotSpecified(const TSourceLoc &location, bool noncoherent);
+
+ bool checkUnsizedArrayConstructorArgumentDimensionality(const TIntermSequence &arguments,
+ TType type,
+ const TSourceLoc &line);
+
+ void checkCombinedClipCullDistanceIsValid(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const int arraySize);
+
+ // Check texture offset is within range.
+ void checkSingleTextureOffset(const TSourceLoc &line,
+ const TConstantUnion *values,
+ size_t size,
+ int minOffsetValue,
+ int maxOffsetValue);
+
+ // Will set the size of the outermost array according to geometry shader input layout.
+ void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
+ const ImmutableString &token,
+ TType *type);
+
+ // Similar, for tessellation shaders.
+ void checkTessellationShaderUnsizedArraysAndSetSize(const TSourceLoc &location,
+ const ImmutableString &token,
+ TType *type);
+
+ // Will size any unsized array type so unsized arrays won't need to be taken into account
+ // further along the line in parsing.
+ void checkIsNotUnsizedArray(const TSourceLoc &line,
+ const char *errorMessage,
+ const ImmutableString &token,
+ TType *arrayType);
+
+ TIntermTyped *addBinaryMathInternal(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc);
+ TIntermTyped *createUnaryMath(TOperator op,
+ TIntermTyped *child,
+ const TSourceLoc &loc,
+ const TFunction *func);
+
+ TIntermTyped *addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc);
+ TIntermTyped *addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line);
+ TIntermTyped *addNonConstructorFunctionCall(TFunctionLookup *fnCall, const TSourceLoc &loc);
+
+ // Return either the original expression or the folded version of the expression in case the
+ // folded node will validate the same way during subsequent parsing.
+ TIntermTyped *expressionOrFoldedResult(TIntermTyped *expression);
+
+ // Return true if the checks pass
+ bool binaryOpCommonCheck(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc);
+
+ TIntermFunctionPrototype *createPrototypeNodeFromFunction(const TFunction &function,
+ const TSourceLoc &location,
+ bool insertParametersToSymbolTable);
+
+ void setAtomicCounterBindingDefaultOffset(const TPublicType &declaration,
+ const TSourceLoc &location);
+
+ bool checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier);
+ bool parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier);
+ bool parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier);
+ void setGeometryShaderInputArraySize(unsigned int inputArraySize, const TSourceLoc &line);
+
+ bool parseTessControlShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier);
+ bool parseTessEvaluationShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier);
+
+ // Certain operations become illegal only iff the shader declares pixel local storage uniforms.
+ enum class PLSIllegalOperations
+ {
+ // When polyfilled with shader images, pixel local storage requires early_fragment_tests,
+ // which causes discard to interact differently with the depth and stencil tests.
+ //
+ // To ensure identical behavior across all backends (some of which may not have access to
+ // early_fragment_tests), we disallow discard if pixel local storage uniforms have been
+ // declared.
+ Discard,
+
+ // ARB_fragment_shader_interlock functions cannot be called within flow control, which
+ // includes any code that might execute after a return statement. To keep things simple, and
+ // since these "interlock" calls are automatically injected by the compiler inside of
+ // main(), we disallow return from main() if pixel local storage uniforms have been
+ // declared.
+ ReturnFromMain,
+
+ // When polyfilled with shader images, pixel local storage requires early_fragment_tests,
+ // which causes assignments to gl_FragDepth(EXT) and gl_SampleMask to be ignored.
+ //
+ // To ensure identical behavior across all backends, we disallow assignment to these values
+ // if pixel local storage uniforms have been declared.
+ AssignFragDepth,
+ AssignSampleMask
+ };
+
+ // Generates an error if any pixel local storage uniforms have been declared (more specifically,
+ // if mPLSBindings is not empty).
+ //
+ // If no pixel local storage uniforms have been declared, and if the PLS extension is enabled,
+ // saves the potential error to mPLSPotentialErrors in case we encounter a PLS uniform later.
+ void errorIfPLSDeclared(const TSourceLoc &, PLSIllegalOperations);
+
+ // Set to true when the last/current declarator list was started with an empty declaration. The
+ // non-empty declaration error check will need to be performed if the empty declaration is
+ // followed by a declarator.
+ bool mDeferredNonEmptyDeclarationErrorCheck;
+
+ sh::GLenum mShaderType; // vertex/fragment/geometry/etc shader
+ ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES/WebGL/etc.
+ ShCompileOptions mCompileOptions; // Options passed to TCompiler
+ int mShaderVersion;
+ TIntermBlock *mTreeRoot; // root of parse tree being created
+ int mLoopNestingLevel; // 0 if outside all loops
+ int mStructNestingLevel; // incremented while parsing a struct declaration
+ int mSwitchNestingLevel; // 0 if outside all switch statements
+ const TType
+ *mCurrentFunctionType; // the return type of the function that's currently being parsed
+ bool mFunctionReturnsValue; // true if a non-void function has a return
+ bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared
+ // without precision, explicit or implicit.
+ bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling
+ // ESSL1.
+ bool mEarlyFragmentTestsSpecified; // true if |layout(early_fragment_tests) in| is specified.
+ bool mHasDiscard; // true if |discard| is encountered in the shader.
+ bool mSampleQualifierSpecified; // true if the |sample| qualifier is used.
+ TLayoutMatrixPacking mDefaultUniformMatrixPacking;
+ TLayoutBlockStorage mDefaultUniformBlockStorage;
+ TLayoutMatrixPacking mDefaultBufferMatrixPacking;
+ TLayoutBlockStorage mDefaultBufferBlockStorage;
+ TString mHashErrMsg;
+ TDiagnostics *mDiagnostics;
+ TDirectiveHandler mDirectiveHandler;
+ angle::pp::Preprocessor mPreprocessor;
+ void *mScanner;
+ int mMinProgramTexelOffset;
+ int mMaxProgramTexelOffset;
+
+ int mMinProgramTextureGatherOffset;
+ int mMaxProgramTextureGatherOffset;
+
+ // keep track of local group size declared in layout. It should be declared only once.
+ bool mComputeShaderLocalSizeDeclared;
+ sh::WorkGroupSize mComputeShaderLocalSize;
+ // keep track of number of views declared in layout.
+ int mNumViews;
+ int mMaxNumViews;
+ int mMaxImageUnits;
+ int mMaxCombinedTextureImageUnits;
+ int mMaxUniformLocations;
+ int mMaxUniformBufferBindings;
+ int mMaxVertexAttribs;
+ int mMaxAtomicCounterBindings;
+ int mMaxShaderStorageBufferBindings;
+
+ // keeps track whether we are declaring / defining a function
+ bool mDeclaringFunction;
+
+ // keeps track whether we are declaring / defining the function main().
+ bool mDeclaringMain;
+
+ // Track the state of each atomic counter binding.
+ std::map<int, AtomicCounterBindingState> mAtomicCounterBindingStates;
+
+ // Track the format of each pixel local storage binding.
+ std::map<int, TLayoutImageInternalFormat> mPLSBindings;
+
+ // Potential errors to generate immediately upon encountering a pixel local storage uniform.
+ std::vector<std::tuple<const TSourceLoc, PLSIllegalOperations>> mPLSPotentialErrors;
+
+ // Track the geometry shader global parameters declared in layout.
+ TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
+ TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
+ int mGeometryShaderInvocations;
+ int mGeometryShaderMaxVertices;
+ int mMaxGeometryShaderInvocations;
+ int mMaxGeometryShaderMaxVertices;
+ unsigned int mGeometryInputArraySize;
+
+ int mMaxPatchVertices;
+ int mTessControlShaderOutputVertices;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputPrimitiveType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputVertexSpacingType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputOrderingType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputPointType;
+ // List of array declarations without an explicit size that have come before layout(vertices=N).
+ // Once the vertex count is specified, these arrays are sized.
+ TVector<TType *> mDeferredArrayTypesToSize;
+ // Whether the |precise| keyword has been seen in the shader.
+ bool mHasAnyPreciseType;
+
+ AdvancedBlendEquations mAdvancedBlendEquations;
+
+ // Track when we add new scope for func body in ESSL 1.00 spec
+ bool mFunctionBodyNewScope;
+
+ ShShaderOutput mOutputType;
+};
+
+int PaParseStrings(size_t count,
+ const char *const string[],
+ const int length[],
+ TParseContext *context);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/PoolAlloc.cpp b/gfx/angle/checkout/src/compiler/translator/PoolAlloc.cpp
new file mode 100644
index 0000000000..1d770c6229
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/PoolAlloc.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/PoolAlloc.h"
+
+#include "common/debug.h"
+#include "common/tls.h"
+
+TLSIndex PoolIndex = TLS_INVALID_INDEX;
+
+bool InitializePoolIndex()
+{
+ ASSERT(PoolIndex == TLS_INVALID_INDEX);
+
+ PoolIndex = CreateTLSIndex(nullptr);
+ return PoolIndex != TLS_INVALID_INDEX;
+}
+
+void FreePoolIndex()
+{
+ ASSERT(PoolIndex != TLS_INVALID_INDEX);
+
+ DestroyTLSIndex(PoolIndex);
+ PoolIndex = TLS_INVALID_INDEX;
+}
+
+angle::PoolAllocator *GetGlobalPoolAllocator()
+{
+ ASSERT(PoolIndex != TLS_INVALID_INDEX);
+ return static_cast<angle::PoolAllocator *>(GetTLSValue(PoolIndex));
+}
+
+void SetGlobalPoolAllocator(angle::PoolAllocator *poolAllocator)
+{
+ ASSERT(PoolIndex != TLS_INVALID_INDEX);
+ SetTLSValue(PoolIndex, poolAllocator);
+}
diff --git a/gfx/angle/checkout/src/compiler/translator/PoolAlloc.h b/gfx/angle/checkout/src/compiler/translator/PoolAlloc.h
new file mode 100644
index 0000000000..98f549b179
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/PoolAlloc.h
@@ -0,0 +1,102 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_POOLALLOC_H_
+#define COMPILER_TRANSLATOR_POOLALLOC_H_
+
+//
+// This header defines the pool_allocator class that allows STL containers
+// to use the angle::PoolAllocator class by using the pool_allocator
+// class as the allocator (second) template argument.
+//
+// It also defines functions for managing the GlobalPoolAllocator used by the compiler.
+//
+
+#include <stddef.h>
+#include <string.h>
+#include <vector>
+
+#include "common/PoolAlloc.h"
+
+//
+// There could potentially be many pools with pops happening at
+// different times. But a simple use is to have a global pop
+// with everyone using the same global allocator.
+//
+extern angle::PoolAllocator *GetGlobalPoolAllocator();
+extern void SetGlobalPoolAllocator(angle::PoolAllocator *poolAllocator);
+
+//
+// This STL compatible allocator is intended to be used as the allocator
+// parameter to templatized STL containers, like vector and map.
+//
+// It will use the pools for allocation, and not
+// do any deallocation, but will still do destruction.
+//
+template <class T>
+class pool_allocator
+{
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T *pointer;
+ typedef const T *const_pointer;
+ typedef T &reference;
+ typedef const T &const_reference;
+ typedef T value_type;
+
+ template <class Other>
+ struct rebind
+ {
+ typedef pool_allocator<Other> other;
+ };
+ pointer address(reference x) const { return &x; }
+ const_pointer address(const_reference x) const { return &x; }
+
+ pool_allocator() {}
+
+ template <class Other>
+ pool_allocator(const pool_allocator<Other> &p)
+ {}
+
+ template <class Other>
+ pool_allocator<T> &operator=(const pool_allocator<Other> &p)
+ {
+ return *this;
+ }
+
+#if defined(__SUNPRO_CC) && !defined(_RWSTD_ALLOCATOR)
+ // libCStd on some platforms have a different allocate/deallocate interface.
+ // Caller pre-bakes sizeof(T) into 'n' which is the number of bytes to be
+ // allocated, not the number of elements.
+ void *allocate(size_type n) { return getAllocator().allocate(n); }
+ void *allocate(size_type n, const void *) { return getAllocator().allocate(n); }
+ void deallocate(void *, size_type) {}
+#else
+ pointer allocate(size_type n)
+ {
+ return static_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
+ }
+ pointer allocate(size_type n, const void *)
+ {
+ return static_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
+ }
+ void deallocate(pointer, size_type) {}
+#endif // _RWSTD_ALLOCATOR
+
+ void construct(pointer p, const T &val) { new ((void *)p) T(val); }
+ void destroy(pointer p) { p->T::~T(); }
+
+ bool operator==(const pool_allocator &rhs) const { return true; }
+ bool operator!=(const pool_allocator &rhs) const { return false; }
+
+ 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; }
+
+ angle::PoolAllocator &getAllocator() const { return *GetGlobalPoolAllocator(); }
+};
+
+#endif // COMPILER_TRANSLATOR_POOLALLOC_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Pragma.h b/gfx/angle/checkout/src/compiler/translator/Pragma.h
new file mode 100644
index 0000000000..c3f5ca2f46
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Pragma.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_PRAGMA_H_
+#define COMPILER_TRANSLATOR_PRAGMA_H_
+
+struct TPragma
+{
+ struct STDGL
+ {
+ STDGL() : invariantAll(false) {}
+
+ bool invariantAll;
+ };
+
+ // By default optimization is turned on and debug is turned off.
+ TPragma() : optimize(true), debug(false) {}
+ TPragma(bool o, bool d) : optimize(o), debug(d) {}
+
+ bool optimize;
+ bool debug;
+ STDGL stdgl;
+};
+
+#endif // COMPILER_TRANSLATOR_PRAGMA_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/QualifierTypes.cpp b/gfx/angle/checkout/src/compiler/translator/QualifierTypes.cpp
new file mode 100644
index 0000000000..e524146cd3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/QualifierTypes.cpp
@@ -0,0 +1,1007 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/QualifierTypes.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+
+#include <algorithm>
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kSpecifiedMultipleTimes(" specified multiple times");
+constexpr const ImmutableString kInvariantMultipleTimes(
+ "The invariant qualifier specified multiple times.");
+constexpr const ImmutableString kPreciseMultipleTimes(
+ "The precise qualifier specified multiple times.");
+constexpr const ImmutableString kPrecisionMultipleTimes(
+ "The precision qualifier specified multiple times.");
+constexpr const ImmutableString kLayoutMultipleTimes(
+ "The layout qualifier specified multiple times.");
+constexpr const ImmutableString kLayoutAndInvariantDisallowed(
+ "The layout qualifier and invariant qualifier cannot coexist in the same "
+ "declaration according to the grammar.");
+constexpr const ImmutableString kInterpolationMultipleTimes(
+ "The interpolation qualifier specified multiple times.");
+constexpr const ImmutableString kOutputLayoutMultipleTimes(
+ "Output layout location specified multiple times.");
+constexpr const ImmutableString kInvariantQualifierFirst(
+ "The invariant qualifier has to be first in the expression.");
+constexpr const ImmutableString kStorageAfterInterpolation(
+ "Storage qualifiers have to be after interpolation qualifiers.");
+constexpr const ImmutableString kPrecisionAfterInterpolation(
+ "Precision qualifiers have to be after interpolation qualifiers.");
+constexpr const ImmutableString kStorageAfterLayout(
+ "Storage qualifiers have to be after layout qualifiers.");
+constexpr const ImmutableString kPrecisionAfterLayout(
+ "Precision qualifiers have to be after layout qualifiers.");
+constexpr const ImmutableString kPrecisionAfterStorage(
+ "Precision qualifiers have to be after storage qualifiers.");
+constexpr const ImmutableString kPrecisionAfterMemory(
+ "Precision qualifiers have to be after memory qualifiers.");
+
+// GLSL ES 3.10 does not impose a strict order on type qualifiers and allows multiple layout
+// declarations.
+// GLSL ES 3.10 Revision 4, 4.10 Order of Qualification
+bool AreTypeQualifierChecksRelaxed(int shaderVersion)
+{
+ return shaderVersion >= 310;
+}
+
+bool IsScopeQualifier(TQualifier qualifier)
+{
+ return qualifier == EvqGlobal || qualifier == EvqTemporary;
+}
+
+bool IsScopeQualifierWrapper(const TQualifierWrapperBase *qualifier)
+{
+ if (qualifier->getType() != QtStorage)
+ return false;
+ const TStorageQualifierWrapper *storageQualifier =
+ static_cast<const TStorageQualifierWrapper *>(qualifier);
+ TQualifier q = storageQualifier->getQualifier();
+ return IsScopeQualifier(q);
+}
+
+// Returns true if the invariant/precise for the qualifier sequence holds
+bool IsInvariantCorrect(const TTypeQualifierBuilder::QualifierSequence &qualifiers)
+{
+ // We should have at least one qualifier.
+ // The first qualifier always tells the scope.
+ return qualifiers.size() >= 1 && IsScopeQualifierWrapper(qualifiers[0]);
+}
+
+ImmutableString QualifierSpecifiedMultipleTimesErrorMessage(const ImmutableString &qualifierString)
+{
+ ImmutableStringBuilder errorMsg(qualifierString.length() + kSpecifiedMultipleTimes.length());
+ errorMsg << qualifierString << kSpecifiedMultipleTimes;
+ return errorMsg;
+}
+
+// Returns true if there are qualifiers which have been specified multiple times
+// If areQualifierChecksRelaxed is set to true, then layout qualifier repetition is allowed.
+bool HasRepeatingQualifiers(const TTypeQualifierBuilder::QualifierSequence &qualifiers,
+ bool areQualifierChecksRelaxed,
+ ImmutableString *errorMessage)
+{
+ bool invariantFound = false;
+ bool preciseFound = false;
+ bool precisionFound = false;
+ bool layoutFound = false;
+ bool interpolationFound = false;
+
+ unsigned int locationsSpecified = 0;
+ bool isOut = false;
+
+ // The iteration starts from one since the first qualifier only reveals the scope of the
+ // expression. It is inserted first whenever the sequence gets created.
+ for (size_t i = 1; i < qualifiers.size(); ++i)
+ {
+ switch (qualifiers[i]->getType())
+ {
+ case QtInvariant:
+ {
+ if (invariantFound)
+ {
+ *errorMessage = kInvariantMultipleTimes;
+ return true;
+ }
+ invariantFound = true;
+ break;
+ }
+ case QtPrecise:
+ {
+ if (preciseFound)
+ {
+ *errorMessage = kPreciseMultipleTimes;
+ return true;
+ }
+ preciseFound = true;
+ break;
+ }
+ case QtPrecision:
+ {
+ if (precisionFound)
+ {
+ *errorMessage = kPrecisionMultipleTimes;
+ return true;
+ }
+ precisionFound = true;
+ break;
+ }
+ case QtLayout:
+ {
+ if (layoutFound && !areQualifierChecksRelaxed)
+ {
+ *errorMessage = kLayoutMultipleTimes;
+ return true;
+ }
+ if (invariantFound && !areQualifierChecksRelaxed)
+ {
+ // This combination is not correct according to the syntax specified in the
+ // formal grammar in the ESSL 3.00 spec. In ESSL 3.10 the grammar does not have
+ // a similar restriction.
+ *errorMessage = kLayoutAndInvariantDisallowed;
+ return true;
+ }
+ layoutFound = true;
+ const TLayoutQualifier &currentQualifier =
+ static_cast<const TLayoutQualifierWrapper *>(qualifiers[i])->getQualifier();
+ locationsSpecified += currentQualifier.locationsSpecified;
+ break;
+ }
+ case QtInterpolation:
+ {
+ // 'centroid' is treated as a storage qualifier
+ // 'flat centroid' will be squashed to 'flat'
+ // 'smooth centroid' will be squashed to 'centroid'
+ if (interpolationFound)
+ {
+ *errorMessage = kInterpolationMultipleTimes;
+ return true;
+ }
+ interpolationFound = true;
+ break;
+ }
+ case QtStorage:
+ {
+ // Go over all of the storage qualifiers up until the current one and check for
+ // repetitions.
+ TQualifier currentQualifier =
+ static_cast<const TStorageQualifierWrapper *>(qualifiers[i])->getQualifier();
+ if (currentQualifier == EvqVertexOut || currentQualifier == EvqFragmentOut ||
+ currentQualifier == EvqFragmentInOut)
+ {
+ isOut = true;
+ }
+ for (size_t j = 1; j < i; ++j)
+ {
+ if (qualifiers[j]->getType() == QtStorage)
+ {
+ const TStorageQualifierWrapper *previousQualifierWrapper =
+ static_cast<const TStorageQualifierWrapper *>(qualifiers[j]);
+ TQualifier previousQualifier = previousQualifierWrapper->getQualifier();
+ if (currentQualifier == previousQualifier)
+ {
+ *errorMessage = QualifierSpecifiedMultipleTimesErrorMessage(
+ previousQualifierWrapper->getQualifierString());
+ return true;
+ }
+ }
+ }
+ break;
+ }
+ case QtMemory:
+ {
+ // Go over all of the memory qualifiers up until the current one and check for
+ // repetitions.
+ // Having both readonly and writeonly in a sequence is valid.
+ // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
+ TQualifier currentQualifier =
+ static_cast<const TMemoryQualifierWrapper *>(qualifiers[i])->getQualifier();
+ for (size_t j = 1; j < i; ++j)
+ {
+ if (qualifiers[j]->getType() == QtMemory)
+ {
+ const TMemoryQualifierWrapper *previousQualifierWrapper =
+ static_cast<const TMemoryQualifierWrapper *>(qualifiers[j]);
+ TQualifier previousQualifier = previousQualifierWrapper->getQualifier();
+ if (currentQualifier == previousQualifier)
+ {
+ *errorMessage = QualifierSpecifiedMultipleTimesErrorMessage(
+ previousQualifierWrapper->getQualifierString());
+ return true;
+ }
+ }
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ if (locationsSpecified > 1 && isOut)
+ {
+ // GLSL ES 3.00.6 section 4.3.8.2 Output Layout Qualifiers
+ // GLSL ES 3.10 section 4.4.2 Output Layout Qualifiers
+ // "The qualifier may appear at most once within a declaration."
+ *errorMessage = kOutputLayoutMultipleTimes;
+ return true;
+ }
+
+ return false;
+}
+
+// GLSL ES 3.00_6, 4.7 Order of Qualification
+// The correct order of qualifiers is:
+// invariant-qualifier interpolation-qualifier storage-qualifier precision-qualifier
+// layout-qualifier has to be before storage-qualifier.
+//
+// GLSL ES 3.1 relaxes the order of qualification:
+// When multiple qualifiers are present in a declaration, they may appear in any order, but they
+// must all appear before the type.
+bool AreQualifiersInOrder(const TTypeQualifierBuilder::QualifierSequence &qualifiers,
+ int shaderVersion,
+ ImmutableString *errorMessage)
+{
+ if (shaderVersion >= 310)
+ {
+ return true;
+ }
+
+ bool foundInterpolation = false;
+ bool foundStorage = false;
+ bool foundPrecision = false;
+ for (size_t i = 1; i < qualifiers.size(); ++i)
+ {
+ switch (qualifiers[i]->getType())
+ {
+ case QtInvariant:
+ if (foundInterpolation || foundStorage || foundPrecision)
+ {
+ *errorMessage = kInvariantQualifierFirst;
+ return false;
+ }
+ break;
+ case QtInterpolation:
+ if (foundStorage)
+ {
+ *errorMessage = kStorageAfterInterpolation;
+ return false;
+ }
+ else if (foundPrecision)
+ {
+ *errorMessage = kPrecisionAfterInterpolation;
+ return false;
+ }
+ foundInterpolation = true;
+ break;
+ case QtLayout:
+ if (foundStorage)
+ {
+ *errorMessage = kStorageAfterLayout;
+ return false;
+ }
+ else if (foundPrecision)
+ {
+ *errorMessage = kPrecisionAfterLayout;
+ return false;
+ }
+ break;
+ case QtStorage:
+ if (foundPrecision)
+ {
+ *errorMessage = kPrecisionAfterStorage;
+ return false;
+ }
+ foundStorage = true;
+ break;
+ case QtMemory:
+ if (foundPrecision)
+ {
+ *errorMessage = kPrecisionAfterMemory;
+ return false;
+ }
+ break;
+ case QtPrecision:
+ foundPrecision = true;
+ break;
+ case QtPrecise:
+ // This keyword is available in ES3.1 (with extension) or in ES3.2, but the function
+ // should early-out in such a case as the spec doesn't require a particular order to
+ // the qualifiers.
+ UNREACHABLE();
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ return true;
+}
+
+struct QualifierComparator
+{
+ bool operator()(const TQualifierWrapperBase *q1, const TQualifierWrapperBase *q2)
+ {
+ return q1->getRank() < q2->getRank();
+ }
+};
+
+void SortSequence(TTypeQualifierBuilder::QualifierSequence &qualifiers)
+{
+ // We need a stable sorting algorithm since the order of layout-qualifier declarations matter.
+ // The sorting starts from index 1, instead of 0, since the element at index 0 tells the scope
+ // and we always want it to be first.
+ std::stable_sort(qualifiers.begin() + 1, qualifiers.end(), QualifierComparator());
+}
+
+// Handles the joining of storage qualifiers for variables.
+bool JoinVariableStorageQualifier(TQualifier *joinedQualifier, TQualifier storageQualifier)
+{
+ switch (*joinedQualifier)
+ {
+ case EvqGlobal:
+ *joinedQualifier = storageQualifier;
+ break;
+ case EvqTemporary:
+ {
+ switch (storageQualifier)
+ {
+ case EvqConst:
+ *joinedQualifier = storageQualifier;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ case EvqSmooth:
+ {
+ switch (storageQualifier)
+ {
+ case EvqCentroid:
+ *joinedQualifier = EvqCentroid;
+ break;
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ *joinedQualifier = EvqSmoothOut;
+ break;
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqSmoothIn;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ case EvqFlat:
+ {
+ switch (storageQualifier)
+ {
+ case EvqCentroid:
+ *joinedQualifier = EvqFlat;
+ break;
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ *joinedQualifier = EvqFlatOut;
+ break;
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqFlatIn;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ case EvqNoPerspective:
+ {
+ switch (storageQualifier)
+ {
+ case EvqCentroid:
+ *joinedQualifier = EvqNoPerspective;
+ break;
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ *joinedQualifier = EvqNoPerspectiveOut;
+ break;
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqNoPerspectiveIn;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ case EvqCentroid:
+ {
+ switch (storageQualifier)
+ {
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ *joinedQualifier = EvqCentroidOut;
+ break;
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqCentroidIn;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ case EvqSample:
+ {
+ switch (storageQualifier)
+ {
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ *joinedQualifier = EvqSampleOut;
+ break;
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqSampleIn;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ case EvqPatch:
+ {
+ switch (storageQualifier)
+ {
+ case EvqTessControlOut:
+ *joinedQualifier = EvqPatchOut;
+ break;
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqPatchIn;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+ return true;
+}
+
+// Handles the joining of storage qualifiers for a parameter in a function.
+bool JoinParameterStorageQualifier(TQualifier *joinedQualifier, TQualifier storageQualifier)
+{
+ switch (*joinedQualifier)
+ {
+ case EvqTemporary:
+ *joinedQualifier = storageQualifier;
+ break;
+ case EvqConst:
+ {
+ switch (storageQualifier)
+ {
+ case EvqParamIn:
+ *joinedQualifier = EvqParamConst;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool JoinMemoryQualifier(TMemoryQualifier *joinedMemoryQualifier, TQualifier memoryQualifier)
+{
+ switch (memoryQualifier)
+ {
+ case EvqReadOnly:
+ joinedMemoryQualifier->readonly = true;
+ break;
+ case EvqWriteOnly:
+ joinedMemoryQualifier->writeonly = true;
+ break;
+ case EvqCoherent:
+ joinedMemoryQualifier->coherent = true;
+ break;
+ case EvqRestrict:
+ joinedMemoryQualifier->restrictQualifier = true;
+ break;
+ case EvqVolatile:
+ // Variables having the volatile qualifier are automatcally treated as coherent as well.
+ // GLSL ES 3.10, Revision 4, 4.9 Memory Access Qualifiers
+ joinedMemoryQualifier->volatileQualifier = true;
+ joinedMemoryQualifier->coherent = true;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ return true;
+}
+
+TTypeQualifier GetVariableTypeQualifierFromSortedSequence(
+ const TTypeQualifierBuilder::QualifierSequence &sortedSequence,
+ TDiagnostics *diagnostics)
+{
+ TTypeQualifier typeQualifier(
+ static_cast<const TStorageQualifierWrapper *>(sortedSequence[0])->getQualifier(),
+ sortedSequence[0]->getLine());
+ for (size_t i = 1; i < sortedSequence.size(); ++i)
+ {
+ const TQualifierWrapperBase *qualifier = sortedSequence[i];
+ bool isQualifierValid = false;
+ switch (qualifier->getType())
+ {
+ case QtInvariant:
+ isQualifierValid = true;
+ typeQualifier.invariant = true;
+ break;
+ case QtPrecise:
+ isQualifierValid = true;
+ typeQualifier.precise = true;
+ break;
+ case QtInterpolation:
+ {
+ switch (typeQualifier.qualifier)
+ {
+ case EvqGlobal:
+ isQualifierValid = true;
+ typeQualifier.qualifier =
+ static_cast<const TInterpolationQualifierWrapper *>(qualifier)
+ ->getQualifier();
+ break;
+ default:
+ isQualifierValid = false;
+ }
+ break;
+ }
+ case QtLayout:
+ {
+ const TLayoutQualifierWrapper *layoutQualifierWrapper =
+ static_cast<const TLayoutQualifierWrapper *>(qualifier);
+ isQualifierValid = true;
+ typeQualifier.layoutQualifier = sh::JoinLayoutQualifiers(
+ typeQualifier.layoutQualifier, layoutQualifierWrapper->getQualifier(),
+ layoutQualifierWrapper->getLine(), diagnostics);
+ break;
+ }
+ case QtStorage:
+ isQualifierValid = JoinVariableStorageQualifier(
+ &typeQualifier.qualifier,
+ static_cast<const TStorageQualifierWrapper *>(qualifier)->getQualifier());
+ break;
+ case QtPrecision:
+ isQualifierValid = true;
+ typeQualifier.precision =
+ static_cast<const TPrecisionQualifierWrapper *>(qualifier)->getQualifier();
+ ASSERT(typeQualifier.precision != EbpUndefined);
+ break;
+ case QtMemory:
+ isQualifierValid = JoinMemoryQualifier(
+ &typeQualifier.memoryQualifier,
+ static_cast<const TMemoryQualifierWrapper *>(qualifier)->getQualifier());
+ break;
+ default:
+ UNREACHABLE();
+ }
+ if (!isQualifierValid)
+ {
+ const ImmutableString &qualifierString = qualifier->getQualifierString();
+ diagnostics->error(qualifier->getLine(), "invalid qualifier combination",
+ qualifierString.data());
+ break;
+ }
+ }
+ return typeQualifier;
+}
+
+TTypeQualifier GetParameterTypeQualifierFromSortedSequence(
+ TBasicType parameterBasicType,
+ const TTypeQualifierBuilder::QualifierSequence &sortedSequence,
+ TDiagnostics *diagnostics)
+{
+ TTypeQualifier typeQualifier(EvqTemporary, sortedSequence[0]->getLine());
+ for (size_t i = 1; i < sortedSequence.size(); ++i)
+ {
+ const TQualifierWrapperBase *qualifier = sortedSequence[i];
+ bool isQualifierValid = false;
+ switch (qualifier->getType())
+ {
+ case QtInvariant:
+ case QtInterpolation:
+ case QtLayout:
+ break;
+ case QtMemory:
+ isQualifierValid = JoinMemoryQualifier(
+ &typeQualifier.memoryQualifier,
+ static_cast<const TMemoryQualifierWrapper *>(qualifier)->getQualifier());
+ break;
+ case QtStorage:
+ isQualifierValid = JoinParameterStorageQualifier(
+ &typeQualifier.qualifier,
+ static_cast<const TStorageQualifierWrapper *>(qualifier)->getQualifier());
+ break;
+ case QtPrecision:
+ isQualifierValid = true;
+ typeQualifier.precision =
+ static_cast<const TPrecisionQualifierWrapper *>(qualifier)->getQualifier();
+ ASSERT(typeQualifier.precision != EbpUndefined);
+ break;
+ case QtPrecise:
+ isQualifierValid = true;
+ typeQualifier.precise = true;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ if (!isQualifierValid)
+ {
+ const ImmutableString &qualifierString = qualifier->getQualifierString();
+ diagnostics->error(qualifier->getLine(), "invalid parameter qualifier",
+ qualifierString.data());
+ break;
+ }
+ }
+
+ switch (typeQualifier.qualifier)
+ {
+ case EvqParamIn:
+ case EvqParamConst: // const in
+ case EvqParamOut:
+ case EvqParamInOut:
+ break;
+ case EvqConst:
+ // Opaque parameters can only be |in|. |const| is allowed, but is meaningless and is
+ // dropped.
+ typeQualifier.qualifier = IsOpaqueType(parameterBasicType) ? EvqParamIn : EvqParamConst;
+ break;
+ case EvqTemporary:
+ // no qualifier has been specified, set it to EvqParamIn which is the default
+ typeQualifier.qualifier = EvqParamIn;
+ break;
+ default:
+ diagnostics->error(sortedSequence[0]->getLine(), "Invalid parameter qualifier ",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ return typeQualifier;
+}
+} // namespace
+
+TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier,
+ TLayoutQualifier rightQualifier,
+ const TSourceLoc &rightQualifierLocation,
+ TDiagnostics *diagnostics)
+{
+ TLayoutQualifier joinedQualifier = leftQualifier;
+
+ if (rightQualifier.location != -1)
+ {
+ joinedQualifier.location = rightQualifier.location;
+ ++joinedQualifier.locationsSpecified;
+ }
+ if (rightQualifier.yuv != false)
+ {
+ joinedQualifier.yuv = rightQualifier.yuv;
+ }
+ if (rightQualifier.earlyFragmentTests != false)
+ {
+ joinedQualifier.earlyFragmentTests = rightQualifier.earlyFragmentTests;
+ }
+ if (rightQualifier.binding != -1)
+ {
+ joinedQualifier.binding = rightQualifier.binding;
+ }
+ if (rightQualifier.offset != -1)
+ {
+ joinedQualifier.offset = rightQualifier.offset;
+ }
+ if (rightQualifier.matrixPacking != EmpUnspecified)
+ {
+ joinedQualifier.matrixPacking = rightQualifier.matrixPacking;
+ }
+ if (rightQualifier.blockStorage != EbsUnspecified)
+ {
+ joinedQualifier.blockStorage = rightQualifier.blockStorage;
+ }
+ if (rightQualifier.noncoherent != false)
+ {
+ joinedQualifier.noncoherent = rightQualifier.noncoherent;
+ }
+
+ for (size_t i = 0u; i < rightQualifier.localSize.size(); ++i)
+ {
+ if (rightQualifier.localSize[i] != -1)
+ {
+ if (joinedQualifier.localSize[i] != -1 &&
+ joinedQualifier.localSize[i] != rightQualifier.localSize[i])
+ {
+ diagnostics->error(rightQualifierLocation,
+ "Cannot have multiple different work group size specifiers",
+ getWorkGroupSizeString(i));
+ }
+ joinedQualifier.localSize[i] = rightQualifier.localSize[i];
+ }
+ }
+
+ if (rightQualifier.numViews != -1)
+ {
+ joinedQualifier.numViews = rightQualifier.numViews;
+ }
+
+ if (rightQualifier.imageInternalFormat != EiifUnspecified)
+ {
+ joinedQualifier.imageInternalFormat = rightQualifier.imageInternalFormat;
+ }
+
+ if (rightQualifier.primitiveType != EptUndefined)
+ {
+ if (joinedQualifier.primitiveType != EptUndefined &&
+ joinedQualifier.primitiveType != rightQualifier.primitiveType)
+ {
+ diagnostics->error(rightQualifierLocation,
+ "Cannot have multiple different primitive specifiers",
+ getGeometryShaderPrimitiveTypeString(rightQualifier.primitiveType));
+ }
+ joinedQualifier.primitiveType = rightQualifier.primitiveType;
+ }
+
+ if (rightQualifier.invocations != 0)
+ {
+ if (joinedQualifier.invocations != 0 &&
+ joinedQualifier.invocations != rightQualifier.invocations)
+ {
+ diagnostics->error(rightQualifierLocation,
+ "Cannot have multiple different invocations specifiers",
+ "invocations");
+ }
+ joinedQualifier.invocations = rightQualifier.invocations;
+ }
+
+ if (rightQualifier.maxVertices != -1)
+ {
+ if (joinedQualifier.maxVertices != -1 &&
+ joinedQualifier.maxVertices != rightQualifier.maxVertices)
+ {
+ diagnostics->error(rightQualifierLocation,
+ "Cannot have multiple different max_vertices specifiers",
+ "max_vertices");
+ }
+ joinedQualifier.maxVertices = rightQualifier.maxVertices;
+ }
+
+ if (rightQualifier.tesPrimitiveType != EtetUndefined)
+ {
+ if (joinedQualifier.tesPrimitiveType == EtetUndefined)
+ {
+ joinedQualifier.tesPrimitiveType = rightQualifier.tesPrimitiveType;
+ }
+ }
+
+ if (rightQualifier.tesVertexSpacingType != EtetUndefined)
+ {
+ if (joinedQualifier.tesVertexSpacingType == EtetUndefined)
+ {
+ joinedQualifier.tesVertexSpacingType = rightQualifier.tesVertexSpacingType;
+ }
+ }
+
+ if (rightQualifier.tesOrderingType != EtetUndefined)
+ {
+ if (joinedQualifier.tesOrderingType == EtetUndefined)
+ {
+ joinedQualifier.tesOrderingType = rightQualifier.tesOrderingType;
+ }
+ }
+
+ if (rightQualifier.tesPointType != EtetUndefined)
+ {
+ if (joinedQualifier.tesPointType == EtetUndefined)
+ {
+ joinedQualifier.tesPointType = rightQualifier.tesPointType;
+ }
+ }
+
+ if (rightQualifier.vertices != 0)
+ {
+ if (joinedQualifier.vertices != 0 && joinedQualifier.vertices != rightQualifier.vertices)
+ {
+ diagnostics->error(rightQualifierLocation,
+ "Cannot have multiple different vertices specifiers", "vertices");
+ }
+ joinedQualifier.vertices = rightQualifier.vertices;
+ }
+
+ if (rightQualifier.index != -1)
+ {
+ if (joinedQualifier.index != -1)
+ {
+ // EXT_blend_func_extended spec: "Each of these qualifiers may appear at most once"
+ diagnostics->error(rightQualifierLocation, "Cannot have multiple index specifiers",
+ "index");
+ }
+ joinedQualifier.index = rightQualifier.index;
+ }
+
+ if (rightQualifier.advancedBlendEquations.any())
+ {
+ joinedQualifier.advancedBlendEquations |= rightQualifier.advancedBlendEquations;
+ }
+
+ return joinedQualifier;
+}
+
+unsigned int TInvariantQualifierWrapper::getRank() const
+{
+ return 0u;
+}
+
+unsigned int TPreciseQualifierWrapper::getRank() const
+{
+ return 1u;
+}
+
+unsigned int TInterpolationQualifierWrapper::getRank() const
+{
+ return 2u;
+}
+
+unsigned int TLayoutQualifierWrapper::getRank() const
+{
+ return 3u;
+}
+
+unsigned int TStorageQualifierWrapper::getRank() const
+{
+ // Force the 'centroid' auxilary storage qualifier to be always first among all storage
+ // qualifiers.
+ if (mStorageQualifier == EvqCentroid)
+ {
+ return 4u;
+ }
+ else
+ {
+ return 5u;
+ }
+}
+
+unsigned int TMemoryQualifierWrapper::getRank() const
+{
+ return 5u;
+}
+
+unsigned int TPrecisionQualifierWrapper::getRank() const
+{
+ return 6u;
+}
+
+TTypeQualifier::TTypeQualifier(TQualifier scope, const TSourceLoc &loc)
+ : layoutQualifier(TLayoutQualifier::Create()),
+ memoryQualifier(TMemoryQualifier::Create()),
+ precision(EbpUndefined),
+ qualifier(scope),
+ invariant(false),
+ precise(false),
+ line(loc)
+{
+ ASSERT(IsScopeQualifier(qualifier));
+}
+
+TTypeQualifierBuilder::TTypeQualifierBuilder(const TStorageQualifierWrapper *scope,
+ int shaderVersion)
+ : mShaderVersion(shaderVersion)
+{
+ ASSERT(IsScopeQualifier(scope->getQualifier()));
+ mQualifiers.push_back(scope);
+}
+
+void TTypeQualifierBuilder::appendQualifier(const TQualifierWrapperBase *qualifier)
+{
+ mQualifiers.push_back(qualifier);
+}
+
+bool TTypeQualifierBuilder::checkSequenceIsValid(TDiagnostics *diagnostics) const
+{
+ bool areQualifierChecksRelaxed = AreTypeQualifierChecksRelaxed(mShaderVersion);
+ ImmutableString errorMessage("");
+ if (HasRepeatingQualifiers(mQualifiers, areQualifierChecksRelaxed, &errorMessage))
+ {
+ diagnostics->error(mQualifiers[0]->getLine(), errorMessage.data(), "qualifier sequence");
+ return false;
+ }
+
+ if (!areQualifierChecksRelaxed &&
+ !AreQualifiersInOrder(mQualifiers, mShaderVersion, &errorMessage))
+ {
+ diagnostics->error(mQualifiers[0]->getLine(), errorMessage.data(), "qualifier sequence");
+ return false;
+ }
+
+ return true;
+}
+
+TTypeQualifier TTypeQualifierBuilder::getParameterTypeQualifier(TBasicType parameterBasicType,
+ TDiagnostics *diagnostics) const
+{
+ ASSERT(IsInvariantCorrect(mQualifiers));
+ ASSERT(static_cast<const TStorageQualifierWrapper *>(mQualifiers[0])->getQualifier() ==
+ EvqTemporary);
+
+ if (!checkSequenceIsValid(diagnostics))
+ {
+ return TTypeQualifier(EvqTemporary, mQualifiers[0]->getLine());
+ }
+
+ // If the qualifier checks are relaxed, then it is easier to sort the qualifiers so
+ // that the order imposed by the GLSL ES 3.00 spec is kept. Then we can use the same code to
+ // combine the qualifiers.
+ if (AreTypeQualifierChecksRelaxed(mShaderVersion))
+ {
+ // Copy the qualifier sequence so that we can sort them.
+ QualifierSequence sortedQualifierSequence = mQualifiers;
+ SortSequence(sortedQualifierSequence);
+ return GetParameterTypeQualifierFromSortedSequence(parameterBasicType,
+ sortedQualifierSequence, diagnostics);
+ }
+ return GetParameterTypeQualifierFromSortedSequence(parameterBasicType, mQualifiers,
+ diagnostics);
+}
+
+TTypeQualifier TTypeQualifierBuilder::getVariableTypeQualifier(TDiagnostics *diagnostics) const
+{
+ ASSERT(IsInvariantCorrect(mQualifiers));
+
+ if (!checkSequenceIsValid(diagnostics))
+ {
+ return TTypeQualifier(
+ static_cast<const TStorageQualifierWrapper *>(mQualifiers[0])->getQualifier(),
+ mQualifiers[0]->getLine());
+ }
+
+ // If the qualifier checks are relaxed, then it is easier to sort the qualifiers so
+ // that the order imposed by the GLSL ES 3.00 spec is kept. Then we can use the same code to
+ // combine the qualifiers.
+ if (AreTypeQualifierChecksRelaxed(mShaderVersion))
+ {
+ // Copy the qualifier sequence so that we can sort them.
+ QualifierSequence sortedQualifierSequence = mQualifiers;
+ SortSequence(sortedQualifierSequence);
+ return GetVariableTypeQualifierFromSortedSequence(sortedQualifierSequence, diagnostics);
+ }
+ return GetVariableTypeQualifierFromSortedSequence(mQualifiers, diagnostics);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/QualifierTypes.h b/gfx/angle/checkout/src/compiler/translator/QualifierTypes.h
new file mode 100644
index 0000000000..b98f300ce8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/QualifierTypes.h
@@ -0,0 +1,214 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_
+#define COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+class TDiagnostics;
+
+TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier,
+ TLayoutQualifier rightQualifier,
+ const TSourceLoc &rightQualifierLocation,
+ TDiagnostics *diagnostics);
+
+enum TQualifierType
+{
+ QtInvariant,
+ QtPrecise,
+ QtInterpolation,
+ QtLayout,
+ QtStorage,
+ QtPrecision,
+ QtMemory
+};
+
+class TQualifierWrapperBase : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TQualifierWrapperBase(const TSourceLoc &line) : mLine(line) {}
+ virtual ~TQualifierWrapperBase() {}
+ virtual TQualifierType getType() const = 0;
+ virtual ImmutableString getQualifierString() const = 0;
+ virtual unsigned int getRank() const = 0;
+ const TSourceLoc &getLine() const { return mLine; }
+
+ private:
+ TSourceLoc mLine;
+};
+
+class TInvariantQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TInvariantQualifierWrapper(const TSourceLoc &line) : TQualifierWrapperBase(line) {}
+ ~TInvariantQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtInvariant; }
+ ImmutableString getQualifierString() const override { return ImmutableString("invariant"); }
+ unsigned int getRank() const override;
+};
+
+class TPreciseQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TPreciseQualifierWrapper(const TSourceLoc &line) : TQualifierWrapperBase(line) {}
+ ~TPreciseQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtPrecise; }
+ ImmutableString getQualifierString() const override { return ImmutableString("precise"); }
+ unsigned int getRank() const override;
+};
+
+class TInterpolationQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TInterpolationQualifierWrapper(TQualifier interpolationQualifier, const TSourceLoc &line)
+ : TQualifierWrapperBase(line), mInterpolationQualifier(interpolationQualifier)
+ {}
+ ~TInterpolationQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtInterpolation; }
+ ImmutableString getQualifierString() const override
+ {
+ return ImmutableString(sh::getQualifierString(mInterpolationQualifier));
+ }
+ TQualifier getQualifier() const { return mInterpolationQualifier; }
+ unsigned int getRank() const override;
+
+ private:
+ TQualifier mInterpolationQualifier;
+};
+
+class TLayoutQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TLayoutQualifierWrapper(TLayoutQualifier layoutQualifier, const TSourceLoc &line)
+ : TQualifierWrapperBase(line), mLayoutQualifier(layoutQualifier)
+ {}
+ ~TLayoutQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtLayout; }
+ ImmutableString getQualifierString() const override { return ImmutableString("layout"); }
+ const TLayoutQualifier &getQualifier() const { return mLayoutQualifier; }
+ unsigned int getRank() const override;
+
+ private:
+ TLayoutQualifier mLayoutQualifier;
+};
+
+class TStorageQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TStorageQualifierWrapper(TQualifier storageQualifier, const TSourceLoc &line)
+ : TQualifierWrapperBase(line), mStorageQualifier(storageQualifier)
+ {}
+ ~TStorageQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtStorage; }
+ ImmutableString getQualifierString() const override
+ {
+ return ImmutableString(sh::getQualifierString(mStorageQualifier));
+ }
+ TQualifier getQualifier() const { return mStorageQualifier; }
+ unsigned int getRank() const override;
+
+ private:
+ TQualifier mStorageQualifier;
+};
+
+class TPrecisionQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TPrecisionQualifierWrapper(TPrecision precisionQualifier, const TSourceLoc &line)
+ : TQualifierWrapperBase(line), mPrecisionQualifier(precisionQualifier)
+ {}
+ ~TPrecisionQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtPrecision; }
+ ImmutableString getQualifierString() const override
+ {
+ return ImmutableString(sh::getPrecisionString(mPrecisionQualifier));
+ }
+ TPrecision getQualifier() const { return mPrecisionQualifier; }
+ unsigned int getRank() const override;
+
+ private:
+ TPrecision mPrecisionQualifier;
+};
+
+class TMemoryQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TMemoryQualifierWrapper(TQualifier memoryQualifier, const TSourceLoc &line)
+ : TQualifierWrapperBase(line), mMemoryQualifier(memoryQualifier)
+ {}
+ ~TMemoryQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtMemory; }
+ ImmutableString getQualifierString() const override
+ {
+ return ImmutableString(sh::getQualifierString(mMemoryQualifier));
+ }
+ TQualifier getQualifier() const { return mMemoryQualifier; }
+ unsigned int getRank() const override;
+
+ private:
+ TQualifier mMemoryQualifier;
+};
+
+// TTypeQualifier tightly covers type_qualifier from the grammar
+struct TTypeQualifier
+{
+ // initializes all of the qualifiers and sets the scope
+ TTypeQualifier(TQualifier scope, const TSourceLoc &loc);
+
+ TLayoutQualifier layoutQualifier;
+ TMemoryQualifier memoryQualifier;
+ TPrecision precision;
+ TQualifier qualifier;
+ bool invariant;
+ bool precise;
+ TSourceLoc line;
+};
+
+// TTypeQualifierBuilder contains all of the qualifiers when type_qualifier gets parsed.
+// It is to be used to validate the qualifier sequence and build a TTypeQualifier from it.
+class TTypeQualifierBuilder : angle::NonCopyable
+{
+ public:
+ using QualifierSequence = TVector<const TQualifierWrapperBase *>;
+
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TTypeQualifierBuilder(const TStorageQualifierWrapper *scope, int shaderVersion);
+ // Adds the passed qualifier to the end of the sequence.
+ void appendQualifier(const TQualifierWrapperBase *qualifier);
+ // Checks for the order of qualification and repeating qualifiers.
+ bool checkSequenceIsValid(TDiagnostics *diagnostics) const;
+ // Goes over the qualifier sequence and parses it to form a type qualifier for a function
+ // parameter.
+ // The returned object is initialized even if the parsing fails.
+ TTypeQualifier getParameterTypeQualifier(TBasicType parameterBasicType,
+ TDiagnostics *diagnostics) const;
+ // Goes over the qualifier sequence and parses it to form a type qualifier for a variable.
+ // The returned object is initialized even if the parsing fails.
+ TTypeQualifier getVariableTypeQualifier(TDiagnostics *diagnostics) const;
+
+ private:
+ QualifierSequence mQualifiers;
+ int mShaderVersion;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.cpp
new file mode 100644
index 0000000000..e43bd44d4a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.cpp
@@ -0,0 +1,989 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ResourcesHLSL.cpp:
+// Methods for GLSL to HLSL translation for uniforms and interface blocks.
+//
+
+#include "compiler/translator/ResourcesHLSL.h"
+
+#include "common/utilities.h"
+#include "compiler/translator/AtomicCounterFunctionHLSL.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/StructureHLSL.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kAngleDecorString("angle_");
+
+static const char *UniformRegisterPrefix(const TType &type)
+{
+ if (IsSampler(type.getBasicType()))
+ {
+ return "s";
+ }
+ else
+ {
+ return "c";
+ }
+}
+
+static TString InterfaceBlockFieldTypeString(const TField &field,
+ TLayoutBlockStorage blockStorage,
+ bool usedStructuredbuffer)
+{
+ const TType &fieldType = *field.type();
+ const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking;
+ ASSERT(matrixPacking != EmpUnspecified);
+ const TStructure *structure = fieldType.getStruct();
+
+ if (fieldType.isMatrix())
+ {
+ // Use HLSL row-major packing for GLSL column-major matrices
+ const TString &matrixPackString =
+ (matrixPacking == EmpRowMajor ? "column_major" : "row_major");
+ return matrixPackString + " " + TypeString(fieldType);
+ }
+ else if (structure)
+ {
+ // If uniform block's layout is std140 and translating it to StructuredBuffer,
+ // should pack structure in the end, in order to fit API buffer.
+ bool forcePackingEnd = usedStructuredbuffer && (blockStorage == EbsStd140);
+ // Use HLSL row-major packing for GLSL column-major matrices
+ return QualifiedStructNameString(*structure, matrixPacking == EmpColumnMajor,
+ blockStorage == EbsStd140, forcePackingEnd);
+ }
+ else
+ {
+ return TypeString(fieldType);
+ }
+}
+
+static TString InterfaceBlockStructName(const TInterfaceBlock &interfaceBlock)
+{
+ return DecoratePrivate(interfaceBlock.name()) + "_type";
+}
+
+void OutputUniformIndexArrayInitializer(TInfoSinkBase &out,
+ const TType &type,
+ unsigned int startIndex)
+{
+ out << "{";
+ TType elementType(type);
+ elementType.toArrayElementType();
+ for (unsigned int i = 0u; i < type.getOutermostArraySize(); ++i)
+ {
+ if (i > 0u)
+ {
+ out << ", ";
+ }
+ if (elementType.isArray())
+ {
+ OutputUniformIndexArrayInitializer(out, elementType,
+ startIndex + i * elementType.getArraySizeProduct());
+ }
+ else
+ {
+ out << (startIndex + i);
+ }
+ }
+ out << "}";
+}
+
+static TString InterfaceBlockScalarVectorFieldPaddingString(const TType &type)
+{
+ switch (type.getBasicType())
+ {
+ case EbtFloat:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "float3 padding;";
+ case 2:
+ return "float2 padding;";
+ case 3:
+ return "float padding;";
+ default:
+ break;
+ }
+ break;
+ case EbtInt:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "int3 padding;";
+ case 2:
+ return "int2 padding;";
+ case 3:
+ return "int padding";
+ default:
+ break;
+ }
+ break;
+ case EbtUInt:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "uint3 padding;";
+ case 2:
+ return "uint2 padding;";
+ case 3:
+ return "uint padding;";
+ default:
+ break;
+ }
+ break;
+ case EbtBool:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "bool3 padding;";
+ case 2:
+ return "bool2 padding;";
+ case 3:
+ return "bool padding;";
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return "";
+}
+
+static bool IsAnyRasterOrdered(const TVector<const TVariable *> &imageVars)
+{
+ for (const TVariable *imageVar : imageVars)
+ {
+ if (imageVar->getType().getLayoutQualifier().rasterOrdered)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // anonymous namespace
+
+ResourcesHLSL::ResourcesHLSL(StructureHLSL *structureHLSL,
+ ShShaderOutput outputType,
+ const std::vector<ShaderVariable> &uniforms,
+ unsigned int firstUniformRegister)
+ : mUniformRegister(firstUniformRegister),
+ mUniformBlockRegister(0),
+ mSRVRegister(0),
+ mUAVRegister(0),
+ mSamplerCount(0),
+ mStructureHLSL(structureHLSL),
+ mOutputType(outputType),
+ mUniforms(uniforms)
+{}
+
+void ResourcesHLSL::reserveUniformRegisters(unsigned int registerCount)
+{
+ mUniformRegister = registerCount;
+}
+
+void ResourcesHLSL::reserveUniformBlockRegisters(unsigned int registerCount)
+{
+ mUniformBlockRegister = registerCount;
+}
+
+const ShaderVariable *ResourcesHLSL::findUniformByName(const ImmutableString &name) const
+{
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
+ {
+ if (name == mUniforms[uniformIndex].name)
+ {
+ return &mUniforms[uniformIndex];
+ }
+ }
+
+ return nullptr;
+}
+
+unsigned int ResourcesHLSL::assignUniformRegister(const TType &type,
+ const ImmutableString &name,
+ unsigned int *outRegisterCount)
+{
+ unsigned int registerIndex;
+ const ShaderVariable *uniform = findUniformByName(name);
+ ASSERT(uniform);
+
+ if (IsSampler(type.getBasicType()) ||
+ (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly))
+ {
+ registerIndex = mSRVRegister;
+ }
+ else if (IsImage(type.getBasicType()))
+ {
+ registerIndex = mUAVRegister;
+ }
+ else
+ {
+ registerIndex = mUniformRegister;
+ }
+
+ if (uniform->name == "angle_DrawID" && uniform->mappedName == "angle_DrawID")
+ {
+ mUniformRegisterMap["gl_DrawID"] = registerIndex;
+ }
+ else
+ {
+ mUniformRegisterMap[uniform->name] = registerIndex;
+ }
+
+ if (uniform->name == "angle_BaseVertex" && uniform->mappedName == "angle_BaseVertex")
+ {
+ mUniformRegisterMap["gl_BaseVertex"] = registerIndex;
+ }
+ else
+ {
+ mUniformRegisterMap[uniform->name] = registerIndex;
+ }
+
+ if (uniform->name == "angle_BaseInstance" && uniform->mappedName == "angle_BaseInstance")
+ {
+ mUniformRegisterMap["gl_BaseInstance"] = registerIndex;
+ }
+ else
+ {
+ mUniformRegisterMap[uniform->name] = registerIndex;
+ }
+
+ unsigned int registerCount = HLSLVariableRegisterCount(*uniform, mOutputType);
+
+ if (IsSampler(type.getBasicType()) ||
+ (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly))
+ {
+ mSRVRegister += registerCount;
+ }
+ else if (IsImage(type.getBasicType()))
+ {
+ mUAVRegister += registerCount;
+ }
+ else
+ {
+ mUniformRegister += registerCount;
+ }
+ if (outRegisterCount)
+ {
+ *outRegisterCount = registerCount;
+ }
+ return registerIndex;
+}
+
+unsigned int ResourcesHLSL::assignSamplerInStructUniformRegister(const TType &type,
+ const TString &name,
+ unsigned int *outRegisterCount)
+{
+ // Sampler that is a field of a uniform structure.
+ ASSERT(IsSampler(type.getBasicType()));
+ unsigned int registerIndex = mSRVRegister;
+ mUniformRegisterMap[std::string(name.c_str())] = registerIndex;
+ unsigned int registerCount = type.isArray() ? type.getArraySizeProduct() : 1u;
+ mSRVRegister += registerCount;
+ if (outRegisterCount)
+ {
+ *outRegisterCount = registerCount;
+ }
+ return registerIndex;
+}
+
+void ResourcesHLSL::outputHLSLSamplerUniformGroup(
+ TInfoSinkBase &out,
+ const HLSLTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ const TMap<const TVariable *, TString> &samplerInStructSymbolsToAPINames,
+ unsigned int *groupTextureRegisterIndex)
+{
+ if (group.empty())
+ {
+ return;
+ }
+ unsigned int groupRegisterCount = 0;
+ for (const TVariable *uniform : group)
+ {
+ const TType &type = uniform->getType();
+ const ImmutableString &name = uniform->name();
+ unsigned int registerCount;
+
+ // The uniform might be just a regular sampler or one extracted from a struct.
+ unsigned int samplerArrayIndex = 0u;
+ const ShaderVariable *uniformByName = findUniformByName(name);
+ if (uniformByName)
+ {
+ samplerArrayIndex = assignUniformRegister(type, name, &registerCount);
+ }
+ else
+ {
+ ASSERT(samplerInStructSymbolsToAPINames.find(uniform) !=
+ samplerInStructSymbolsToAPINames.end());
+ samplerArrayIndex = assignSamplerInStructUniformRegister(
+ type, samplerInStructSymbolsToAPINames.at(uniform), &registerCount);
+ }
+ groupRegisterCount += registerCount;
+
+ if (type.isArray())
+ {
+ out << "static const uint " << DecorateVariableIfNeeded(*uniform) << ArrayString(type)
+ << " = ";
+ OutputUniformIndexArrayInitializer(out, type, samplerArrayIndex);
+ out << ";\n";
+ }
+ else
+ {
+ out << "static const uint " << DecorateVariableIfNeeded(*uniform) << " = "
+ << samplerArrayIndex << ";\n";
+ }
+ }
+ TString suffix = TextureGroupSuffix(textureGroup);
+ // Since HLSL_TEXTURE_2D is the first group, it has a fixed offset of zero.
+ if (textureGroup != HLSL_TEXTURE_2D)
+ {
+ out << "static const uint textureIndexOffset" << suffix << " = "
+ << (*groupTextureRegisterIndex) << ";\n";
+ out << "static const uint samplerIndexOffset" << suffix << " = "
+ << (*groupTextureRegisterIndex) << ";\n";
+ }
+ out << "uniform " << TextureString(textureGroup) << " textures" << suffix << "["
+ << groupRegisterCount << "]"
+ << " : register(t" << (*groupTextureRegisterIndex) << ");\n";
+ out << "uniform " << SamplerString(textureGroup) << " samplers" << suffix << "["
+ << groupRegisterCount << "]"
+ << " : register(s" << (*groupTextureRegisterIndex) << ");\n";
+ *groupTextureRegisterIndex += groupRegisterCount;
+}
+
+void ResourcesHLSL::outputHLSLImageUniformIndices(TInfoSinkBase &out,
+ const TVector<const TVariable *> &group,
+ unsigned int imageArrayIndex,
+ unsigned int *groupRegisterCount)
+{
+ for (const TVariable *uniform : group)
+ {
+ const TType &type = uniform->getType();
+ const ImmutableString &name = uniform->name();
+ unsigned int registerCount = 0;
+
+ assignUniformRegister(type, name, &registerCount);
+ *groupRegisterCount += registerCount;
+
+ if (type.isArray())
+ {
+ out << "static const uint " << DecorateVariableIfNeeded(*uniform) << ArrayString(type)
+ << " = ";
+ OutputUniformIndexArrayInitializer(out, type, imageArrayIndex);
+ out << ";\n";
+ }
+ else
+ {
+ out << "static const uint " << DecorateVariableIfNeeded(*uniform) << " = "
+ << imageArrayIndex << ";\n";
+ }
+
+ imageArrayIndex += registerCount;
+ }
+}
+
+void ResourcesHLSL::outputHLSLReadonlyImageUniformGroup(TInfoSinkBase &out,
+ const HLSLTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ unsigned int *groupTextureRegisterIndex)
+{
+ if (group.empty())
+ {
+ return;
+ }
+
+ unsigned int groupRegisterCount = 0;
+ outputHLSLImageUniformIndices(out, group, *groupTextureRegisterIndex, &groupRegisterCount);
+
+ TString suffix = TextureGroupSuffix(textureGroup);
+ out << "static const uint readonlyImageIndexOffset" << suffix << " = "
+ << (*groupTextureRegisterIndex) << ";\n";
+ out << "uniform " << TextureString(textureGroup) << " readonlyImages" << suffix << "["
+ << groupRegisterCount << "]"
+ << " : register(t" << (*groupTextureRegisterIndex) << ");\n";
+ *groupTextureRegisterIndex += groupRegisterCount;
+}
+
+void ResourcesHLSL::outputHLSLImageUniformGroup(TInfoSinkBase &out,
+ const HLSLRWTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ unsigned int *groupTextureRegisterIndex)
+{
+ if (group.empty())
+ {
+ return;
+ }
+
+ // ROVs should all be written out in DynamicImage2DHLSL.cpp.
+ ASSERT(!IsAnyRasterOrdered(group));
+
+ unsigned int groupRegisterCount = 0;
+ outputHLSLImageUniformIndices(out, group, *groupTextureRegisterIndex, &groupRegisterCount);
+
+ TString suffix = RWTextureGroupSuffix(textureGroup);
+ out << "static const uint imageIndexOffset" << suffix << " = " << (*groupTextureRegisterIndex)
+ << ";\n";
+ out << "uniform " << RWTextureString(textureGroup) << " images" << suffix << "["
+ << groupRegisterCount << "]"
+ << " : register(u" << (*groupTextureRegisterIndex) << ");\n";
+ *groupTextureRegisterIndex += groupRegisterCount;
+}
+
+void ResourcesHLSL::outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out,
+ const TType &type,
+ const TVariable &variable,
+ const unsigned int registerIndex)
+{
+ out << "uniform " << SamplerString(type.getBasicType()) << " sampler_"
+ << DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(s"
+ << str(registerIndex) << ");\n";
+ out << "uniform " << TextureString(type.getBasicType()) << " texture_"
+ << DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(t"
+ << str(registerIndex) << ");\n";
+}
+
+void ResourcesHLSL::outputUniform(TInfoSinkBase &out,
+ const TType &type,
+ const TVariable &variable,
+ const unsigned int registerIndex)
+{
+ const TStructure *structure = type.getStruct();
+ // If this is a nameless struct, we need to use its full definition, rather than its (empty)
+ // name.
+ // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for
+ // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers
+ // are permitted.
+ const TString &typeName = ((structure && structure->symbolType() != SymbolType::Empty)
+ ? QualifiedStructNameString(*structure, false, false, false)
+ : TypeString(type));
+
+ const TString &registerString =
+ TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")";
+
+ out << "uniform " << typeName << " ";
+
+ out << DecorateVariableIfNeeded(variable);
+
+ out << ArrayString(type) << " : " << registerString << ";\n";
+}
+
+void ResourcesHLSL::outputAtomicCounterBuffer(TInfoSinkBase &out,
+ const int binding,
+ const unsigned int registerIndex)
+{
+ // Atomic counter memory access is not incoherent
+ out << "uniform globallycoherent RWByteAddressBuffer "
+ << getAtomicCounterNameForBinding(binding) << " : register(u" << registerIndex << ");\n";
+}
+
+void ResourcesHLSL::uniformsHeader(TInfoSinkBase &out,
+ ShShaderOutput outputType,
+ const ReferencedVariables &referencedUniforms,
+ TSymbolTable *symbolTable)
+{
+ if (!referencedUniforms.empty())
+ {
+ out << "// Uniforms\n\n";
+ }
+ // In the case of HLSL 4, sampler uniforms need to be grouped by type before the code is
+ // written. They are grouped based on the combination of the HLSL texture type and
+ // HLSL sampler type, enumerated in HLSLTextureSamplerGroup.
+ TVector<TVector<const TVariable *>> groupedSamplerUniforms(HLSL_TEXTURE_MAX + 1);
+ TMap<const TVariable *, TString> samplerInStructSymbolsToAPINames;
+ TVector<TVector<const TVariable *>> groupedReadonlyImageUniforms(HLSL_TEXTURE_MAX + 1);
+ TVector<TVector<const TVariable *>> groupedImageUniforms(HLSL_RWTEXTURE_MAX + 1);
+
+ TUnorderedMap<int, unsigned int> assignedAtomicCounterBindings;
+ unsigned int reservedReadonlyImageRegisterCount = 0, reservedImageRegisterCount = 0;
+ for (auto &uniformIt : referencedUniforms)
+ {
+ // Output regular uniforms. Group sampler uniforms by type.
+ const TVariable &variable = *uniformIt.second;
+ const TType &type = variable.getType();
+
+ if (outputType == SH_HLSL_4_1_OUTPUT && IsSampler(type.getBasicType()))
+ {
+ HLSLTextureGroup group = TextureGroup(type.getBasicType());
+ groupedSamplerUniforms[group].push_back(&variable);
+ }
+ else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(type.getBasicType()))
+ {
+ unsigned int registerIndex = assignUniformRegister(type, variable.name(), nullptr);
+ outputHLSL4_0_FL9_3Sampler(out, type, variable, registerIndex);
+ }
+ else if (outputType == SH_HLSL_4_1_OUTPUT && IsImage(type.getBasicType()))
+ {
+ if (IsImage2D(type.getBasicType()))
+ {
+ const ShaderVariable *uniform = findUniformByName(variable.name());
+ if (type.getMemoryQualifier().readonly)
+ {
+ reservedReadonlyImageRegisterCount +=
+ HLSLVariableRegisterCount(*uniform, mOutputType);
+ }
+ else
+ {
+ reservedImageRegisterCount += HLSLVariableRegisterCount(*uniform, mOutputType);
+ }
+ continue;
+ }
+ if (type.getMemoryQualifier().readonly)
+ {
+ HLSLTextureGroup group = TextureGroup(
+ type.getBasicType(), type.getLayoutQualifier().imageInternalFormat);
+ groupedReadonlyImageUniforms[group].push_back(&variable);
+ }
+ else
+ {
+ HLSLRWTextureGroup group = RWTextureGroup(
+ type.getBasicType(), type.getLayoutQualifier().imageInternalFormat);
+ groupedImageUniforms[group].push_back(&variable);
+ }
+ }
+ else if (outputType == SH_HLSL_4_1_OUTPUT && IsAtomicCounter(type.getBasicType()))
+ {
+ TLayoutQualifier layout = type.getLayoutQualifier();
+ int binding = layout.binding;
+ unsigned int registerIndex;
+ if (assignedAtomicCounterBindings.find(binding) == assignedAtomicCounterBindings.end())
+ {
+ registerIndex = mUAVRegister++;
+ assignedAtomicCounterBindings[binding] = registerIndex;
+ outputAtomicCounterBuffer(out, binding, registerIndex);
+ }
+ else
+ {
+ registerIndex = assignedAtomicCounterBindings[binding];
+ }
+ const ShaderVariable *uniform = findUniformByName(variable.name());
+ mUniformRegisterMap[uniform->name] = registerIndex;
+ }
+ else
+ {
+ if (type.isStructureContainingSamplers())
+ {
+ TVector<const TVariable *> samplerSymbols;
+ TMap<const TVariable *, TString> symbolsToAPINames;
+ ImmutableStringBuilder namePrefix(kAngleDecorString.length() +
+ variable.name().length());
+ namePrefix << kAngleDecorString;
+ namePrefix << variable.name();
+ type.createSamplerSymbols(namePrefix, TString(variable.name().data()),
+ &samplerSymbols, &symbolsToAPINames, symbolTable);
+ for (const TVariable *sampler : samplerSymbols)
+ {
+ const TType &samplerType = sampler->getType();
+
+ if (outputType == SH_HLSL_4_1_OUTPUT)
+ {
+ HLSLTextureGroup group = TextureGroup(samplerType.getBasicType());
+ groupedSamplerUniforms[group].push_back(sampler);
+ samplerInStructSymbolsToAPINames[sampler] = symbolsToAPINames[sampler];
+ }
+ else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ unsigned int registerIndex = assignSamplerInStructUniformRegister(
+ samplerType, symbolsToAPINames[sampler], nullptr);
+ outputHLSL4_0_FL9_3Sampler(out, samplerType, *sampler, registerIndex);
+ }
+ else
+ {
+ ASSERT(outputType == SH_HLSL_3_0_OUTPUT);
+ unsigned int registerIndex = assignSamplerInStructUniformRegister(
+ samplerType, symbolsToAPINames[sampler], nullptr);
+ outputUniform(out, samplerType, *sampler, registerIndex);
+ }
+ }
+ }
+ unsigned int registerIndex = assignUniformRegister(type, variable.name(), nullptr);
+ outputUniform(out, type, variable, registerIndex);
+ }
+ }
+
+ if (outputType == SH_HLSL_4_1_OUTPUT)
+ {
+ unsigned int groupTextureRegisterIndex = 0;
+ // Atomic counters and RW texture share the same resources. Therefore, RW texture need to
+ // start counting after the last atomic counter.
+ unsigned int groupRWTextureRegisterIndex = mUAVRegister;
+ // TEXTURE_2D is special, index offset is assumed to be 0 and omitted in that case.
+ ASSERT(HLSL_TEXTURE_MIN == HLSL_TEXTURE_2D);
+ for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId)
+ {
+ outputHLSLSamplerUniformGroup(
+ out, HLSLTextureGroup(groupId), groupedSamplerUniforms[groupId],
+ samplerInStructSymbolsToAPINames, &groupTextureRegisterIndex);
+ }
+ mSamplerCount = groupTextureRegisterIndex;
+
+ // Reserve t type register for readonly image2D variables.
+ mReadonlyImage2DRegisterIndex = mSRVRegister;
+ groupTextureRegisterIndex += reservedReadonlyImageRegisterCount;
+ mSRVRegister += reservedReadonlyImageRegisterCount;
+
+ for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId)
+ {
+ outputHLSLReadonlyImageUniformGroup(out, HLSLTextureGroup(groupId),
+ groupedReadonlyImageUniforms[groupId],
+ &groupTextureRegisterIndex);
+ }
+ mReadonlyImageCount = groupTextureRegisterIndex - mReadonlyImage2DRegisterIndex;
+ if (mReadonlyImageCount)
+ {
+ out << "static const uint readonlyImageIndexStart = " << mReadonlyImage2DRegisterIndex
+ << ";\n";
+ }
+
+ // Reserve u type register for writable image2D variables.
+ mImage2DRegisterIndex = mUAVRegister;
+ groupRWTextureRegisterIndex += reservedImageRegisterCount;
+ mUAVRegister += reservedImageRegisterCount;
+
+ for (int groupId = HLSL_RWTEXTURE_MIN; groupId < HLSL_RWTEXTURE_MAX; ++groupId)
+ {
+ outputHLSLImageUniformGroup(out, HLSLRWTextureGroup(groupId),
+ groupedImageUniforms[groupId],
+ &groupRWTextureRegisterIndex);
+ }
+ mImageCount = groupRWTextureRegisterIndex - mImage2DRegisterIndex;
+ if (mImageCount)
+ {
+ out << "static const uint imageIndexStart = " << mImage2DRegisterIndex << ";\n";
+ }
+ }
+}
+
+void ResourcesHLSL::samplerMetadataUniforms(TInfoSinkBase &out, unsigned int regIndex)
+{
+ // If mSamplerCount is 0 the shader doesn't use any textures for samplers.
+ if (mSamplerCount > 0)
+ {
+ out << " struct SamplerMetadata\n"
+ " {\n"
+ " int baseLevel;\n"
+ " int internalFormatBits;\n"
+ " int wrapModes;\n"
+ " int padding;\n"
+ " int4 intBorderColor;\n"
+ " };\n"
+ " SamplerMetadata samplerMetadata["
+ << mSamplerCount << "] : packoffset(c" << regIndex << ");\n";
+ }
+}
+
+void ResourcesHLSL::imageMetadataUniforms(TInfoSinkBase &out, unsigned int regIndex)
+{
+ if (mReadonlyImageCount > 0 || mImageCount > 0)
+ {
+ out << " struct ImageMetadata\n"
+ " {\n"
+ " int layer;\n"
+ " uint level;\n"
+ " int2 padding;\n"
+ " };\n";
+
+ if (mReadonlyImageCount > 0)
+ {
+ out << " ImageMetadata readonlyImageMetadata[" << mReadonlyImageCount
+ << "] : packoffset(c" << regIndex << ");\n";
+ }
+
+ if (mImageCount > 0)
+ {
+ out << " ImageMetadata imageMetadata[" << mImageCount << "] : packoffset(c"
+ << regIndex + mReadonlyImageCount << ");\n";
+ }
+ }
+}
+
+TString ResourcesHLSL::uniformBlocksHeader(
+ const ReferencedInterfaceBlocks &referencedInterfaceBlocks,
+ const std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap)
+{
+ TString interfaceBlocks;
+
+ for (const auto &blockReference : referencedInterfaceBlocks)
+ {
+ const TInterfaceBlock &interfaceBlock = *blockReference.second->block;
+ const TVariable *instanceVariable = blockReference.second->instanceVariable;
+ if (instanceVariable != nullptr)
+ {
+ interfaceBlocks += uniformBlockStructString(interfaceBlock);
+ }
+
+ // In order to avoid compile performance issue, translate uniform block to structured
+ // buffer. anglebug.com/3682.
+ if (uniformBlockOptimizedMap.count(interfaceBlock.uniqueId().get()) != 0)
+ {
+ unsigned int structuredBufferRegister = mSRVRegister;
+ if (instanceVariable != nullptr && instanceVariable->getType().isArray())
+ {
+ unsigned int instanceArraySize =
+ instanceVariable->getType().getOutermostArraySize();
+ for (unsigned int arrayIndex = 0; arrayIndex < instanceArraySize; arrayIndex++)
+ {
+ interfaceBlocks += uniformBlockWithOneLargeArrayMemberString(
+ interfaceBlock, instanceVariable, structuredBufferRegister + arrayIndex,
+ arrayIndex);
+ }
+ mSRVRegister += instanceArraySize;
+ }
+ else
+ {
+ interfaceBlocks += uniformBlockWithOneLargeArrayMemberString(
+ interfaceBlock, instanceVariable, structuredBufferRegister, GL_INVALID_INDEX);
+ mSRVRegister += 1u;
+ }
+ mUniformBlockRegisterMap[interfaceBlock.name().data()] = structuredBufferRegister;
+ mUniformBlockUseStructuredBufferMap[interfaceBlock.name().data()] = true;
+ continue;
+ }
+
+ unsigned int activeRegister = mUniformBlockRegister;
+ mUniformBlockRegisterMap[interfaceBlock.name().data()] = activeRegister;
+
+ if (instanceVariable != nullptr && instanceVariable->getType().isArray())
+ {
+ unsigned int instanceArraySize = instanceVariable->getType().getOutermostArraySize();
+ for (unsigned int arrayIndex = 0; arrayIndex < instanceArraySize; arrayIndex++)
+ {
+ interfaceBlocks += uniformBlockString(interfaceBlock, instanceVariable,
+ activeRegister + arrayIndex, arrayIndex);
+ }
+ mUniformBlockRegister += instanceArraySize;
+ }
+ else
+ {
+ interfaceBlocks += uniformBlockString(interfaceBlock, instanceVariable, activeRegister,
+ GL_INVALID_INDEX);
+ mUniformBlockRegister += 1u;
+ }
+ }
+
+ return (interfaceBlocks.empty() ? "" : ("// Uniform Blocks\n\n" + interfaceBlocks));
+}
+
+void ResourcesHLSL::allocateShaderStorageBlockRegisters(
+ const ReferencedInterfaceBlocks &referencedInterfaceBlocks)
+{
+ for (const auto &interfaceBlockReference : referencedInterfaceBlocks)
+ {
+ const TInterfaceBlock &interfaceBlock = *interfaceBlockReference.second->block;
+ const TVariable *instanceVariable = interfaceBlockReference.second->instanceVariable;
+
+ mShaderStorageBlockRegisterMap[interfaceBlock.name().data()] = mUAVRegister;
+
+ if (instanceVariable != nullptr && instanceVariable->getType().isArray())
+ {
+ mUAVRegister += instanceVariable->getType().getOutermostArraySize();
+ }
+ else
+ {
+ mUAVRegister += 1u;
+ }
+ }
+}
+
+TString ResourcesHLSL::shaderStorageBlocksHeader(
+ const ReferencedInterfaceBlocks &referencedInterfaceBlocks)
+{
+ TString interfaceBlocks;
+
+ for (const auto &interfaceBlockReference : referencedInterfaceBlocks)
+ {
+ const TInterfaceBlock &interfaceBlock = *interfaceBlockReference.second->block;
+ const TVariable *instanceVariable = interfaceBlockReference.second->instanceVariable;
+
+ unsigned int activeRegister = mShaderStorageBlockRegisterMap[interfaceBlock.name().data()];
+
+ if (instanceVariable != nullptr && instanceVariable->getType().isArray())
+ {
+ unsigned int instanceArraySize = instanceVariable->getType().getOutermostArraySize();
+ for (unsigned int arrayIndex = 0; arrayIndex < instanceArraySize; arrayIndex++)
+ {
+ interfaceBlocks += shaderStorageBlockString(
+ interfaceBlock, instanceVariable, activeRegister + arrayIndex, arrayIndex);
+ }
+ }
+ else
+ {
+ interfaceBlocks += shaderStorageBlockString(interfaceBlock, instanceVariable,
+ activeRegister, GL_INVALID_INDEX);
+ }
+ }
+
+ return interfaceBlocks;
+}
+
+TString ResourcesHLSL::uniformBlockString(const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex)
+{
+ const TString &arrayIndexString = (arrayIndex != GL_INVALID_INDEX ? str(arrayIndex) : "");
+ const TString &blockName = TString(interfaceBlock.name().data()) + arrayIndexString;
+ TString hlsl;
+
+ hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) +
+ ")\n"
+ "{\n";
+
+ if (instanceVariable != nullptr)
+ {
+ hlsl += " " + InterfaceBlockStructName(interfaceBlock) + " " +
+ InterfaceBlockInstanceString(instanceVariable->name(), arrayIndex) + ";\n";
+ }
+ else
+ {
+ const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
+ hlsl += uniformBlockMembersString(interfaceBlock, blockStorage);
+ }
+
+ hlsl += "};\n\n";
+
+ return hlsl;
+}
+
+TString ResourcesHLSL::uniformBlockWithOneLargeArrayMemberString(
+ const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex)
+{
+ TString hlsl, typeString;
+
+ const TField &field = *interfaceBlock.fields()[0];
+ const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
+ typeString = InterfaceBlockFieldTypeString(field, blockStorage, true);
+ const TType &fieldType = *field.type();
+ if (fieldType.isMatrix())
+ {
+ if (arrayIndex == GL_INVALID_INDEX || arrayIndex == 0)
+ {
+ hlsl += "struct pack" + Decorate(interfaceBlock.name()) + " { " + typeString + " " +
+ Decorate(field.name()) + "; };\n";
+ }
+ typeString = "pack" + Decorate(interfaceBlock.name());
+ }
+ else if (fieldType.isVectorArray() || fieldType.isScalarArray())
+ {
+ // If the member is an array of scalars or vectors, std140 rules require the base array
+ // stride are rounded up to the base alignment of a vec4.
+ if (arrayIndex == GL_INVALID_INDEX || arrayIndex == 0)
+ {
+ hlsl += "struct pack" + Decorate(interfaceBlock.name()) + " { " + typeString + " " +
+ Decorate(field.name()) + ";\n";
+ hlsl += InterfaceBlockScalarVectorFieldPaddingString(fieldType) + " };\n";
+ }
+ typeString = "pack" + Decorate(interfaceBlock.name());
+ }
+
+ if (instanceVariable != nullptr)
+ {
+
+ hlsl += "StructuredBuffer <" + typeString + "> " +
+ InterfaceBlockInstanceString(instanceVariable->name(), arrayIndex) + "_" +
+ Decorate(field.name()) + +" : register(t" + str(registerIndex) + ");\n";
+ }
+ else
+ {
+ hlsl += "StructuredBuffer <" + typeString + "> " + Decorate(field.name()) +
+ " : register(t" + str(registerIndex) + ");\n";
+ }
+
+ return hlsl;
+}
+
+TString ResourcesHLSL::shaderStorageBlockString(const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex)
+{
+ TString hlsl;
+ if (instanceVariable != nullptr)
+ {
+ hlsl += "RWByteAddressBuffer " +
+ InterfaceBlockInstanceString(instanceVariable->name(), arrayIndex) +
+ ": register(u" + str(registerIndex) + ");\n";
+ }
+ else
+ {
+ hlsl += "RWByteAddressBuffer " + Decorate(interfaceBlock.name()) + ": register(u" +
+ str(registerIndex) + ");\n";
+ }
+ return hlsl;
+}
+
+TString ResourcesHLSL::InterfaceBlockInstanceString(const ImmutableString &instanceName,
+ unsigned int arrayIndex)
+{
+ if (arrayIndex != GL_INVALID_INDEX)
+ {
+ return DecoratePrivate(instanceName) + "_" + str(arrayIndex);
+ }
+ else
+ {
+ return Decorate(instanceName);
+ }
+}
+
+TString ResourcesHLSL::uniformBlockMembersString(const TInterfaceBlock &interfaceBlock,
+ TLayoutBlockStorage blockStorage)
+{
+ TString hlsl;
+
+ Std140PaddingHelper padHelper = mStructureHLSL->getPaddingHelper();
+
+ const unsigned int fieldCount = static_cast<unsigned int>(interfaceBlock.fields().size());
+ for (unsigned int typeIndex = 0; typeIndex < fieldCount; typeIndex++)
+ {
+ const TField &field = *interfaceBlock.fields()[typeIndex];
+ const TType &fieldType = *field.type();
+
+ if (blockStorage == EbsStd140)
+ {
+ // 2 and 3 component vector types in some cases need pre-padding
+ hlsl += padHelper.prePaddingString(fieldType, false);
+ }
+
+ hlsl += " " + InterfaceBlockFieldTypeString(field, blockStorage, false) + " " +
+ Decorate(field.name()) + ArrayString(fieldType).data() + ";\n";
+
+ // must pad out after matrices and arrays, where HLSL usually allows itself room to pack
+ // stuff
+ if (blockStorage == EbsStd140)
+ {
+ const bool useHLSLRowMajorPacking =
+ (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor);
+ hlsl += padHelper.postPaddingString(fieldType, useHLSLRowMajorPacking,
+ typeIndex == fieldCount - 1, false);
+ }
+ }
+
+ return hlsl;
+}
+
+TString ResourcesHLSL::uniformBlockStructString(const TInterfaceBlock &interfaceBlock)
+{
+ const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
+
+ return "struct " + InterfaceBlockStructName(interfaceBlock) +
+ "\n"
+ "{\n" +
+ uniformBlockMembersString(interfaceBlock, blockStorage) + "};\n\n";
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.h b/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.h
new file mode 100644
index 0000000000..a13ba036eb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.h
@@ -0,0 +1,155 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ResourcesHLSL.h:
+// Methods for GLSL to HLSL translation for uniforms and interface blocks.
+//
+
+#ifndef COMPILER_TRANSLATOR_RESOURCESHLSL_H_
+#define COMPILER_TRANSLATOR_RESOURCESHLSL_H_
+
+#include "compiler/translator/OutputHLSL.h"
+#include "compiler/translator/UtilsHLSL.h"
+
+namespace sh
+{
+class ImmutableString;
+class StructureHLSL;
+class TSymbolTable;
+
+class ResourcesHLSL : angle::NonCopyable
+{
+ public:
+ ResourcesHLSL(StructureHLSL *structureHLSL,
+ ShShaderOutput outputType,
+ const std::vector<ShaderVariable> &uniforms,
+ unsigned int firstUniformRegister);
+
+ void reserveUniformRegisters(unsigned int registerCount);
+ void reserveUniformBlockRegisters(unsigned int registerCount);
+ void uniformsHeader(TInfoSinkBase &out,
+ ShShaderOutput outputType,
+ const ReferencedVariables &referencedUniforms,
+ TSymbolTable *symbolTable);
+
+ // Must be called after uniformsHeader
+ void samplerMetadataUniforms(TInfoSinkBase &out, unsigned int regIndex);
+ unsigned int getSamplerCount() const { return mSamplerCount; }
+ void imageMetadataUniforms(TInfoSinkBase &out, unsigned int regIndex);
+ TString uniformBlocksHeader(
+ const ReferencedInterfaceBlocks &referencedInterfaceBlocks,
+ const std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap);
+ void allocateShaderStorageBlockRegisters(
+ const ReferencedInterfaceBlocks &referencedInterfaceBlocks);
+ TString shaderStorageBlocksHeader(const ReferencedInterfaceBlocks &referencedInterfaceBlocks);
+
+ // Used for direct index references
+ static TString InterfaceBlockInstanceString(const ImmutableString &instanceName,
+ unsigned int arrayIndex);
+
+ const std::map<std::string, unsigned int> &getShaderStorageBlockRegisterMap() const
+ {
+ return mShaderStorageBlockRegisterMap;
+ }
+
+ const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const
+ {
+ return mUniformBlockRegisterMap;
+ }
+
+ const std::map<std::string, bool> &getUniformBlockUseStructuredBufferMap() const
+ {
+ return mUniformBlockUseStructuredBufferMap;
+ }
+
+ const std::map<std::string, unsigned int> &getUniformRegisterMap() const
+ {
+ return mUniformRegisterMap;
+ }
+
+ unsigned int getReadonlyImage2DRegisterIndex() const { return mReadonlyImage2DRegisterIndex; }
+ unsigned int getImage2DRegisterIndex() const { return mImage2DRegisterIndex; }
+ bool hasImages() const { return mReadonlyImageCount > 0 || mImageCount > 0; }
+
+ private:
+ TString uniformBlockString(const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex);
+ TString uniformBlockWithOneLargeArrayMemberString(const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex);
+
+ TString shaderStorageBlockString(const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex);
+ TString uniformBlockMembersString(const TInterfaceBlock &interfaceBlock,
+ TLayoutBlockStorage blockStorage);
+ TString uniformBlockStructString(const TInterfaceBlock &interfaceBlock);
+ const ShaderVariable *findUniformByName(const ImmutableString &name) const;
+
+ void outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out,
+ const TType &type,
+ const TVariable &variable,
+ const unsigned int registerIndex);
+ void outputUniform(TInfoSinkBase &out,
+ const TType &type,
+ const TVariable &variable,
+ const unsigned int registerIndex);
+ void outputAtomicCounterBuffer(TInfoSinkBase &out,
+ const int binding,
+ const unsigned int registerIndex);
+
+ // Returns the uniform's register index
+ unsigned int assignUniformRegister(const TType &type,
+ const ImmutableString &name,
+ unsigned int *outRegisterCount);
+ unsigned int assignSamplerInStructUniformRegister(const TType &type,
+ const TString &name,
+ unsigned int *outRegisterCount);
+
+ void outputHLSLSamplerUniformGroup(
+ TInfoSinkBase &out,
+ const HLSLTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ const TMap<const TVariable *, TString> &samplerInStructSymbolsToAPINames,
+ unsigned int *groupTextureRegisterIndex);
+
+ void outputHLSLImageUniformIndices(TInfoSinkBase &out,
+ const TVector<const TVariable *> &group,
+ unsigned int imageArrayIndex,
+ unsigned int *groupRegisterCount);
+ void outputHLSLReadonlyImageUniformGroup(TInfoSinkBase &out,
+ const HLSLTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ unsigned int *groupTextureRegisterIndex);
+ void outputHLSLImageUniformGroup(TInfoSinkBase &out,
+ const HLSLRWTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ unsigned int *groupTextureRegisterIndex);
+
+ unsigned int mUniformRegister;
+ unsigned int mUniformBlockRegister;
+ unsigned int mSRVRegister;
+ unsigned int mUAVRegister;
+ unsigned int mSamplerCount;
+ unsigned int mReadonlyImageCount = 0;
+ unsigned int mImageCount = 0;
+ StructureHLSL *mStructureHLSL;
+ ShShaderOutput mOutputType;
+
+ const std::vector<ShaderVariable> &mUniforms;
+ std::map<std::string, unsigned int> mUniformBlockRegisterMap;
+ std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap;
+ std::map<std::string, unsigned int> mUniformRegisterMap;
+ std::map<std::string, bool> mUniformBlockUseStructuredBufferMap;
+ unsigned int mReadonlyImage2DRegisterIndex;
+ unsigned int mImage2DRegisterIndex;
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_RESOURCESHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Severity.h b/gfx/angle/checkout/src/compiler/translator/Severity.h
new file mode 100644
index 0000000000..dccd45375d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Severity.h
@@ -0,0 +1,22 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_SEVERITY_H_
+#define COMPILER_TRANSLATOR_SEVERITY_H_
+
+namespace sh
+{
+
+// Severity is used to classify info log messages.
+enum Severity
+{
+ SH_WARNING,
+ SH_ERROR
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SEVERITY_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp b/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp
new file mode 100644
index 0000000000..abc680656a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp
@@ -0,0 +1,1091 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+//
+// Implement the top-level of interface to the compiler,
+// as defined in ShaderLang.h
+//
+
+#include "GLSLANG/ShaderLang.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/InitializeDll.h"
+#include "compiler/translator/glslang_wrapper.h"
+#include "compiler/translator/length_limits.h"
+#ifdef ANGLE_ENABLE_HLSL
+# include "compiler/translator/TranslatorHLSL.h"
+#endif // ANGLE_ENABLE_HLSL
+#include "angle_gl.h"
+#include "compiler/translator/VariablePacker.h"
+
+namespace sh
+{
+
+namespace
+{
+
+bool isInitialized = false;
+
+// glslang can only be initialized/finalized once per process. Otherwise, the following EGL commands
+// will call GlslangFinalize() without ever being able to GlslangInitialize() again, leading to
+// crashes since GlslangFinalize() cleans up glslang for the entire process.
+// dpy1 = eglGetPlatformDisplay() |
+// eglInitialize(dpy1) | GlslangInitialize()
+// dpy2 = eglGetPlatformDisplay() |
+// eglInitialize(dpy2) | GlslangInitialize()
+// eglTerminate(dpy2) | GlslangFinalize()
+// eglInitialize(dpy1) | Display::isInitialized() == true, no GlslangInitialize()
+int initializeGlslangRefCount = 0;
+
+//
+// This is the platform independent interface between an OGL driver
+// and the shading language compiler.
+//
+
+template <typename VarT>
+const std::vector<VarT> *GetVariableList(const TCompiler *compiler);
+
+template <>
+const std::vector<InterfaceBlock> *GetVariableList(const TCompiler *compiler)
+{
+ return &compiler->getInterfaceBlocks();
+}
+
+TCompiler *GetCompilerFromHandle(ShHandle handle)
+{
+ if (!handle)
+ {
+ return nullptr;
+ }
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ return base->getAsCompiler();
+}
+
+template <typename VarT>
+const std::vector<VarT> *GetShaderVariables(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (!compiler)
+ {
+ return nullptr;
+ }
+
+ return GetVariableList<VarT>(compiler);
+}
+
+#ifdef ANGLE_ENABLE_HLSL
+TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
+{
+ if (!handle)
+ return nullptr;
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ return base->getAsTranslatorHLSL();
+}
+#endif // ANGLE_ENABLE_HLSL
+
+GLenum GetGeometryShaderPrimitiveTypeEnum(sh::TLayoutPrimitiveType primitiveType)
+{
+ switch (primitiveType)
+ {
+ case EptPoints:
+ return GL_POINTS;
+ case EptLines:
+ return GL_LINES;
+ case EptLinesAdjacency:
+ return GL_LINES_ADJACENCY_EXT;
+ case EptTriangles:
+ return GL_TRIANGLES;
+ case EptTrianglesAdjacency:
+ return GL_TRIANGLES_ADJACENCY_EXT;
+
+ case EptLineStrip:
+ return GL_LINE_STRIP;
+ case EptTriangleStrip:
+ return GL_TRIANGLE_STRIP;
+
+ case EptUndefined:
+ default:
+ UNREACHABLE();
+ return GL_INVALID_VALUE;
+ }
+}
+
+GLenum GetTessellationShaderTypeEnum(sh::TLayoutTessEvaluationType type)
+{
+ switch (type)
+ {
+ case EtetTriangles:
+ return GL_TRIANGLES;
+ case EtetQuads:
+ return GL_QUADS;
+ case EtetIsolines:
+ return GL_ISOLINES;
+ case EtetEqualSpacing:
+ return GL_EQUAL;
+ case EtetFractionalEvenSpacing:
+ return GL_FRACTIONAL_EVEN;
+ case EtetFractionalOddSpacing:
+ return GL_FRACTIONAL_ODD;
+ case EtetCw:
+ return GL_CW;
+ case EtetCcw:
+ return GL_CCW;
+ case EtetPointMode:
+ return GL_TESS_GEN_POINT_MODE;
+
+ case EtetUndefined:
+ default:
+ UNREACHABLE();
+ return GL_INVALID_VALUE;
+ }
+}
+
+} // anonymous namespace
+
+//
+// Driver must call this first, once, before doing any other compiler operations.
+// Subsequent calls to this function are no-op.
+//
+bool Initialize()
+{
+ if (!isInitialized)
+ {
+ isInitialized = InitProcess();
+ }
+ return isInitialized;
+}
+
+//
+// Cleanup symbol tables
+//
+bool Finalize()
+{
+ if (isInitialized)
+ {
+ DetachProcess();
+ isInitialized = false;
+ }
+ return true;
+}
+
+//
+// Initialize built-in resources with minimum expected values.
+//
+void InitBuiltInResources(ShBuiltInResources *resources)
+{
+ // Make comparable.
+ memset(resources, 0, sizeof(*resources));
+
+ // Constants.
+ resources->MaxVertexAttribs = 8;
+ resources->MaxVertexUniformVectors = 128;
+ resources->MaxVaryingVectors = 8;
+ resources->MaxVertexTextureImageUnits = 0;
+ resources->MaxCombinedTextureImageUnits = 8;
+ resources->MaxTextureImageUnits = 8;
+ resources->MaxFragmentUniformVectors = 16;
+ resources->MaxDrawBuffers = 1;
+
+ // Extensions.
+ resources->OES_standard_derivatives = 0;
+ resources->OES_EGL_image_external = 0;
+ resources->OES_EGL_image_external_essl3 = 0;
+ resources->NV_EGL_stream_consumer_external = 0;
+ resources->ARB_texture_rectangle = 0;
+ resources->EXT_blend_func_extended = 0;
+ resources->EXT_draw_buffers = 0;
+ resources->EXT_frag_depth = 0;
+ resources->EXT_shader_texture_lod = 0;
+ resources->EXT_shader_framebuffer_fetch = 0;
+ resources->EXT_shader_framebuffer_fetch_non_coherent = 0;
+ resources->NV_shader_framebuffer_fetch = 0;
+ resources->ARM_shader_framebuffer_fetch = 0;
+ resources->OVR_multiview = 0;
+ resources->OVR_multiview2 = 0;
+ resources->EXT_YUV_target = 0;
+ resources->EXT_geometry_shader = 0;
+ resources->OES_geometry_shader = 0;
+ resources->EXT_gpu_shader5 = 0;
+ resources->OES_shader_io_blocks = 0;
+ resources->EXT_shader_io_blocks = 0;
+ resources->EXT_shader_non_constant_global_initializers = 0;
+ resources->NV_shader_noperspective_interpolation = 0;
+ resources->OES_texture_storage_multisample_2d_array = 0;
+ resources->OES_texture_3D = 0;
+ resources->ANGLE_shader_pixel_local_storage = 0;
+ resources->ANGLE_texture_multisample = 0;
+ resources->ANGLE_multi_draw = 0;
+ resources->ANGLE_base_vertex_base_instance = 0;
+ resources->ANGLE_base_vertex_base_instance_shader_builtin = 0;
+ resources->WEBGL_video_texture = 0;
+ resources->APPLE_clip_distance = 0;
+ resources->OES_texture_cube_map_array = 0;
+ resources->EXT_texture_cube_map_array = 0;
+ resources->EXT_shadow_samplers = 0;
+ resources->OES_shader_multisample_interpolation = 0;
+ resources->NV_draw_buffers = 0;
+ resources->OES_shader_image_atomic = 0;
+ resources->EXT_tessellation_shader = 0;
+ resources->OES_texture_buffer = 0;
+ resources->EXT_texture_buffer = 0;
+ resources->OES_sample_variables = 0;
+ resources->EXT_clip_cull_distance = 0;
+ resources->KHR_blend_equation_advanced = 0;
+
+ resources->MaxClipDistances = 8;
+ resources->MaxCullDistances = 8;
+ resources->MaxCombinedClipAndCullDistances = 8;
+
+ // Disable highp precision in fragment shader by default.
+ resources->FragmentPrecisionHigh = 0;
+
+ // GLSL ES 3.0 constants.
+ resources->MaxVertexOutputVectors = 16;
+ resources->MaxFragmentInputVectors = 15;
+ resources->MinProgramTexelOffset = -8;
+ resources->MaxProgramTexelOffset = 7;
+
+ // Extensions constants.
+ resources->MaxDualSourceDrawBuffers = 0;
+
+ resources->MaxViewsOVR = 4;
+
+ // Disable name hashing by default.
+ resources->HashFunction = nullptr;
+
+ resources->MaxExpressionComplexity = 256;
+ resources->MaxCallStackDepth = 256;
+ resources->MaxFunctionParameters = 1024;
+
+ // ES 3.1 Revision 4, 7.2 Built-in Constants
+
+ // ES 3.1, Revision 4, 8.13 Texture minification
+ // "The value of MIN_PROGRAM_TEXTURE_GATHER_OFFSET must be less than or equal to the value of
+ // MIN_PROGRAM_TEXEL_OFFSET. The value of MAX_PROGRAM_TEXTURE_GATHER_OFFSET must be greater than
+ // or equal to the value of MAX_PROGRAM_TEXEL_OFFSET"
+ resources->MinProgramTextureGatherOffset = -8;
+ resources->MaxProgramTextureGatherOffset = 7;
+
+ resources->MaxImageUnits = 4;
+ resources->MaxVertexImageUniforms = 0;
+ resources->MaxFragmentImageUniforms = 0;
+ resources->MaxComputeImageUniforms = 4;
+ resources->MaxCombinedImageUniforms = 4;
+
+ resources->MaxUniformLocations = 1024;
+
+ resources->MaxCombinedShaderOutputResources = 4;
+
+ resources->MaxComputeWorkGroupCount[0] = 65535;
+ resources->MaxComputeWorkGroupCount[1] = 65535;
+ resources->MaxComputeWorkGroupCount[2] = 65535;
+ resources->MaxComputeWorkGroupSize[0] = 128;
+ resources->MaxComputeWorkGroupSize[1] = 128;
+ resources->MaxComputeWorkGroupSize[2] = 64;
+ resources->MaxComputeUniformComponents = 512;
+ resources->MaxComputeTextureImageUnits = 16;
+
+ resources->MaxComputeAtomicCounters = 8;
+ resources->MaxComputeAtomicCounterBuffers = 1;
+
+ resources->MaxVertexAtomicCounters = 0;
+ resources->MaxFragmentAtomicCounters = 0;
+ resources->MaxCombinedAtomicCounters = 8;
+ resources->MaxAtomicCounterBindings = 1;
+
+ resources->MaxVertexAtomicCounterBuffers = 0;
+ resources->MaxFragmentAtomicCounterBuffers = 0;
+ resources->MaxCombinedAtomicCounterBuffers = 1;
+ resources->MaxAtomicCounterBufferSize = 32;
+
+ resources->MaxUniformBufferBindings = 32;
+ resources->MaxShaderStorageBufferBindings = 4;
+
+ resources->MaxGeometryUniformComponents = 1024;
+ resources->MaxGeometryUniformBlocks = 12;
+ resources->MaxGeometryInputComponents = 64;
+ resources->MaxGeometryOutputComponents = 64;
+ resources->MaxGeometryOutputVertices = 256;
+ resources->MaxGeometryTotalOutputComponents = 1024;
+ resources->MaxGeometryTextureImageUnits = 16;
+ resources->MaxGeometryAtomicCounterBuffers = 0;
+ resources->MaxGeometryAtomicCounters = 0;
+ resources->MaxGeometryShaderStorageBlocks = 0;
+ resources->MaxGeometryShaderInvocations = 32;
+ resources->MaxGeometryImageUniforms = 0;
+
+ resources->MaxTessControlInputComponents = 64;
+ resources->MaxTessControlOutputComponents = 64;
+ resources->MaxTessControlTextureImageUnits = 16;
+ resources->MaxTessControlUniformComponents = 1024;
+ resources->MaxTessControlTotalOutputComponents = 2048;
+ resources->MaxTessControlImageUniforms = 0;
+ resources->MaxTessControlAtomicCounters = 0;
+ resources->MaxTessControlAtomicCounterBuffers = 0;
+
+ resources->MaxTessPatchComponents = 120;
+ resources->MaxPatchVertices = 32;
+ resources->MaxTessGenLevel = 64;
+
+ resources->MaxTessEvaluationInputComponents = 64;
+ resources->MaxTessEvaluationOutputComponents = 64;
+ resources->MaxTessEvaluationTextureImageUnits = 16;
+ resources->MaxTessEvaluationUniformComponents = 1024;
+ resources->MaxTessEvaluationImageUniforms = 0;
+ resources->MaxTessEvaluationAtomicCounters = 0;
+ resources->MaxTessEvaluationAtomicCounterBuffers = 0;
+
+ resources->SubPixelBits = 8;
+
+ resources->MaxSamples = 4;
+}
+
+//
+// Driver calls these to create and destroy compiler objects.
+//
+ShHandle ConstructCompiler(sh::GLenum type,
+ ShShaderSpec spec,
+ ShShaderOutput output,
+ const ShBuiltInResources *resources)
+{
+ TShHandleBase *base = static_cast<TShHandleBase *>(ConstructCompiler(type, spec, output));
+ if (base == nullptr)
+ {
+ return 0;
+ }
+
+ TCompiler *compiler = base->getAsCompiler();
+ if (compiler == nullptr)
+ {
+ return 0;
+ }
+
+ // Generate built-in symbol table.
+ if (!compiler->Init(*resources))
+ {
+ Destruct(base);
+ return 0;
+ }
+
+ return base;
+}
+
+void Destruct(ShHandle handle)
+{
+ if (handle == 0)
+ return;
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+
+ if (base->getAsCompiler())
+ DeleteCompiler(base->getAsCompiler());
+}
+
+ShBuiltInResources GetBuiltInResources(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getBuiltInResources();
+}
+
+const std::string &GetBuiltInResourcesString(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getBuiltInResourcesString();
+}
+
+//
+// Do an actual compile on the given strings. The result is left
+// in the given compile object.
+//
+// Return: The return value of ShCompile is really boolean, indicating
+// success or failure.
+//
+bool Compile(const ShHandle handle,
+ const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ return compiler->compile(shaderStrings, numStrings, compileOptions);
+}
+
+void ClearResults(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ compiler->clearResults();
+}
+
+int GetShaderVersion(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getShaderVersion();
+}
+
+ShShaderOutput GetShaderOutputType(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getOutputType();
+}
+
+//
+// Return any compiler log of messages for the application.
+//
+const std::string &GetInfoLog(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ TInfoSink &infoSink = compiler->getInfoSink();
+ return infoSink.info.str();
+}
+
+//
+// Return any object code.
+//
+const std::string &GetObjectCode(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ TInfoSink &infoSink = compiler->getInfoSink();
+ return infoSink.obj.str();
+}
+
+//
+// Return any object binary code.
+//
+const BinaryBlob &GetObjectBinaryBlob(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ TInfoSink &infoSink = compiler->getInfoSink();
+ return infoSink.obj.getBinary();
+}
+
+const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return &(compiler->getNameMap());
+}
+
+const std::vector<ShaderVariable> *GetUniforms(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (!compiler)
+ {
+ return nullptr;
+ }
+ return &compiler->getUniforms();
+}
+
+const std::vector<ShaderVariable> *GetInputVaryings(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return nullptr;
+ }
+ return &compiler->getInputVaryings();
+}
+
+const std::vector<ShaderVariable> *GetOutputVaryings(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return nullptr;
+ }
+ return &compiler->getOutputVaryings();
+}
+
+const std::vector<ShaderVariable> *GetVaryings(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return nullptr;
+ }
+
+ switch (compiler->getShaderType())
+ {
+ case GL_VERTEX_SHADER:
+ return &compiler->getOutputVaryings();
+ case GL_FRAGMENT_SHADER:
+ return &compiler->getInputVaryings();
+ case GL_COMPUTE_SHADER:
+ ASSERT(compiler->getOutputVaryings().empty() && compiler->getInputVaryings().empty());
+ return &compiler->getOutputVaryings();
+ // Since geometry shaders have both input and output varyings, we shouldn't call GetVaryings
+ // on a geometry shader.
+ default:
+ return nullptr;
+ }
+}
+
+const std::vector<ShaderVariable> *GetAttributes(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (!compiler)
+ {
+ return nullptr;
+ }
+ return &compiler->getAttributes();
+}
+
+const std::vector<ShaderVariable> *GetOutputVariables(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (!compiler)
+ {
+ return nullptr;
+ }
+ return &compiler->getOutputVariables();
+}
+
+const std::vector<InterfaceBlock> *GetInterfaceBlocks(const ShHandle handle)
+{
+ return GetShaderVariables<InterfaceBlock>(handle);
+}
+
+const std::vector<InterfaceBlock> *GetUniformBlocks(const ShHandle handle)
+{
+ ASSERT(handle);
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return &compiler->getUniformBlocks();
+}
+
+const std::vector<InterfaceBlock> *GetShaderStorageBlocks(const ShHandle handle)
+{
+ ASSERT(handle);
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return &compiler->getShaderStorageBlocks();
+}
+
+WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getComputeShaderLocalSize();
+}
+
+int GetVertexShaderNumViews(const ShHandle handle)
+{
+ ASSERT(handle);
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getNumViews();
+}
+
+bool EnablesPerSampleShading(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return false;
+ }
+ return compiler->enablesPerSampleShading();
+}
+
+uint32_t GetShaderSpecConstUsageBits(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return 0;
+ }
+ return compiler->getSpecConstUsageBits().bits();
+}
+
+bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector<ShaderVariable> &variables)
+{
+ return CheckVariablesInPackingLimits(maxVectors, variables);
+}
+
+bool GetShaderStorageBlockRegister(const ShHandle handle,
+ const std::string &shaderStorageBlockName,
+ unsigned int *indexOut)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ ASSERT(indexOut);
+
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ if (!translator->hasShaderStorageBlock(shaderStorageBlockName))
+ {
+ return false;
+ }
+
+ *indexOut = translator->getShaderStorageBlockRegister(shaderStorageBlockName);
+ return true;
+#else
+ return false;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+bool GetUniformBlockRegister(const ShHandle handle,
+ const std::string &uniformBlockName,
+ unsigned int *indexOut)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ ASSERT(indexOut);
+
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ if (!translator->hasUniformBlock(uniformBlockName))
+ {
+ return false;
+ }
+
+ *indexOut = translator->getUniformBlockRegister(uniformBlockName);
+ return true;
+#else
+ return false;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+bool ShouldUniformBlockUseStructuredBuffer(const ShHandle handle,
+ const std::string &uniformBlockName)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->shouldUniformBlockUseStructuredBuffer(uniformBlockName);
+#else
+ return false;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->getUniformRegisterMap();
+#else
+ return nullptr;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+const std::set<std::string> *GetSlowCompilingUniformBlockSet(const ShHandle handle)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->getSlowCompilingUniformBlockSet();
+#else
+ return nullptr;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+unsigned int GetReadonlyImage2DRegisterIndex(const ShHandle handle)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->getReadonlyImage2DRegisterIndex();
+#else
+ return 0;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+unsigned int GetImage2DRegisterIndex(const ShHandle handle)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->getImage2DRegisterIndex();
+#else
+ return 0;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+const std::set<std::string> *GetUsedImage2DFunctionNames(const ShHandle handle)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->getUsedImage2DFunctionNames();
+#else
+ return nullptr;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+bool HasDiscardInFragmentShader(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getShaderType() == GL_FRAGMENT_SHADER && compiler->hasDiscard();
+}
+
+bool HasValidGeometryShaderInputPrimitiveType(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getGeometryShaderInputPrimitiveType() != EptUndefined;
+}
+
+bool HasValidGeometryShaderOutputPrimitiveType(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getGeometryShaderOutputPrimitiveType() != EptUndefined;
+}
+
+bool HasValidGeometryShaderMaxVertices(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getGeometryShaderMaxVertices() >= 0;
+}
+
+bool HasValidTessGenMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputPrimitiveType() != EtetUndefined;
+}
+
+bool HasValidTessGenSpacing(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputVertexSpacingType() != EtetUndefined;
+}
+
+bool HasValidTessGenVertexOrder(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputOrderingType() != EtetUndefined;
+}
+
+bool HasValidTessGenPointMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputPointType() != EtetUndefined;
+}
+
+GLenum GetGeometryShaderInputPrimitiveType(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderInputPrimitiveType());
+}
+
+GLenum GetGeometryShaderOutputPrimitiveType(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderOutputPrimitiveType());
+}
+
+int GetGeometryShaderInvocations(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getGeometryShaderInvocations();
+}
+
+int GetGeometryShaderMaxVertices(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ int maxVertices = compiler->getGeometryShaderMaxVertices();
+ ASSERT(maxVertices >= 0);
+ return maxVertices;
+}
+
+int GetTessControlShaderVertices(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ int vertices = compiler->getTessControlShaderOutputVertices();
+ return vertices;
+}
+
+GLenum GetTessGenMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputPrimitiveType());
+}
+
+GLenum GetTessGenSpacing(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputVertexSpacingType());
+}
+
+GLenum GetTessGenVertexOrder(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputOrderingType());
+}
+
+GLenum GetTessGenPointMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputPointType());
+}
+
+unsigned int GetShaderSharedMemorySize(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ unsigned int sharedMemorySize = compiler->getSharedMemorySize();
+ return sharedMemorySize;
+}
+
+uint32_t GetAdvancedBlendEquations(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ return compiler->getAdvancedBlendEquations().bits();
+}
+
+void InitializeGlslang()
+{
+ if (initializeGlslangRefCount == 0)
+ {
+ GlslangInitialize();
+ }
+ ++initializeGlslangRefCount;
+ ASSERT(initializeGlslangRefCount < std::numeric_limits<int>::max());
+}
+
+void FinalizeGlslang()
+{
+ --initializeGlslangRefCount;
+ ASSERT(initializeGlslangRefCount >= 0);
+ if (initializeGlslangRefCount == 0)
+ {
+ GlslangFinalize();
+ }
+}
+
+// Can't prefix with just _ because then we might introduce a double underscore, which is not safe
+// in GLSL (ESSL 3.00.6 section 3.8: All identifiers containing a double underscore are reserved for
+// use by the underlying implementation). u is short for user-defined.
+const char kUserDefinedNamePrefix[] = "_u";
+
+namespace vk
+{
+// Interface block name containing the aggregate default uniforms
+const char kDefaultUniformsNameVS[] = "defaultUniformsVS";
+const char kDefaultUniformsNameTCS[] = "defaultUniformsTCS";
+const char kDefaultUniformsNameTES[] = "defaultUniformsTES";
+const char kDefaultUniformsNameGS[] = "defaultUniformsGS";
+const char kDefaultUniformsNameFS[] = "defaultUniformsFS";
+const char kDefaultUniformsNameCS[] = "defaultUniformsCS";
+
+// Interface block and variable names containing driver uniforms
+const char kDriverUniformsBlockName[] = "ANGLEUniformBlock";
+const char kDriverUniformsVarName[] = "ANGLEUniforms";
+
+// Interface block array name used for atomic counter emulation
+const char kAtomicCountersBlockName[] = "ANGLEAtomicCounters";
+
+const char kXfbEmulationGetOffsetsFunctionName[] = "ANGLEGetXfbOffsets";
+const char kXfbEmulationCaptureFunctionName[] = "ANGLECaptureXfb";
+const char kXfbEmulationBufferBlockName[] = "ANGLEXfbBuffer";
+const char kXfbEmulationBufferName[] = "ANGLEXfb";
+const char kXfbEmulationBufferFieldName[] = "xfbOut";
+
+const char kTransformPositionFunctionName[] = "ANGLETransformPosition";
+
+const char kXfbExtensionPositionOutName[] = "ANGLEXfbPosition";
+
+// EXT_shader_framebuffer_fetch / EXT_shader_framebuffer_fetch_non_coherent
+const char kInputAttachmentName[] = "ANGLEInputAttachment";
+
+} // namespace vk
+
+const char *BlockLayoutTypeToString(BlockLayoutType type)
+{
+ switch (type)
+ {
+ case BlockLayoutType::BLOCKLAYOUT_STD140:
+ return "std140";
+ case BlockLayoutType::BLOCKLAYOUT_STD430:
+ return "std430";
+ case BlockLayoutType::BLOCKLAYOUT_PACKED:
+ return "packed";
+ case BlockLayoutType::BLOCKLAYOUT_SHARED:
+ return "shared";
+ default:
+ return "invalid";
+ }
+}
+
+const char *BlockTypeToString(BlockType type)
+{
+ switch (type)
+ {
+ case BlockType::BLOCK_BUFFER:
+ return "buffer";
+ case BlockType::BLOCK_UNIFORM:
+ return "uniform";
+ default:
+ return "invalid";
+ }
+}
+
+const char *InterpolationTypeToString(InterpolationType type)
+{
+ switch (type)
+ {
+ case InterpolationType::INTERPOLATION_SMOOTH:
+ return "smooth";
+ case InterpolationType::INTERPOLATION_CENTROID:
+ return "centroid";
+ case InterpolationType::INTERPOLATION_SAMPLE:
+ return "sample";
+ case InterpolationType::INTERPOLATION_FLAT:
+ return "flat";
+ case InterpolationType::INTERPOLATION_NOPERSPECTIVE:
+ return "noperspective";
+ default:
+ return "invalid";
+ }
+}
+} // namespace sh
+
+ShCompileOptions::ShCompileOptions()
+{
+ memset(this, 0, sizeof(*this));
+}
+
+ShCompileOptions::ShCompileOptions(const ShCompileOptions &other)
+{
+ memcpy(this, &other, sizeof(*this));
+}
+ShCompileOptions &ShCompileOptions::operator=(const ShCompileOptions &other)
+{
+ memcpy(this, &other, sizeof(*this));
+ return *this;
+}
+
+ShBuiltInResources::ShBuiltInResources()
+{
+ memset(this, 0, sizeof(*this));
+}
+
+ShBuiltInResources::ShBuiltInResources(const ShBuiltInResources &other)
+{
+ memcpy(this, &other, sizeof(*this));
+}
+ShBuiltInResources &ShBuiltInResources::operator=(const ShBuiltInResources &other)
+{
+ memcpy(this, &other, sizeof(*this));
+ return *this;
+}
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp
new file mode 100644
index 0000000000..f4eeab5ab9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp
@@ -0,0 +1,439 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ShaderStorageBlockFunctionHLSL: Wrapper functions for RWByteAddressBuffer Load/Store functions.
+//
+
+#include "compiler/translator/ShaderStorageBlockFunctionHLSL.h"
+
+#include "common/utilities.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/blocklayout.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOLoadFunctionBody(
+ TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction)
+{
+ const char *convertString;
+ switch (ssboFunction.type.getBasicType())
+ {
+ case EbtFloat:
+ convertString = "asfloat(";
+ break;
+ case EbtInt:
+ convertString = "asint(";
+ break;
+ case EbtUInt:
+ convertString = "asuint(";
+ break;
+ case EbtBool:
+ convertString = "asint(";
+ break;
+ default:
+ UNREACHABLE();
+ return;
+ }
+
+ size_t bytesPerComponent =
+ gl::VariableComponentSize(gl::VariableComponentType(GLVariableType(ssboFunction.type)));
+ out << " " << ssboFunction.typeString << " result";
+ if (ssboFunction.type.isScalar())
+ {
+ size_t offset = ssboFunction.swizzleOffsets[0] * bytesPerComponent;
+ out << " = " << convertString << "buffer.Load(loc + " << offset << "));\n ";
+ }
+ else if (ssboFunction.type.isVector())
+ {
+ if (ssboFunction.rowMajor || !ssboFunction.isDefaultSwizzle)
+ {
+ size_t componentStride = bytesPerComponent;
+ if (ssboFunction.rowMajor)
+ {
+ componentStride = ssboFunction.matrixStride;
+ }
+
+ out << " = {";
+ for (const int offset : ssboFunction.swizzleOffsets)
+ {
+ size_t offsetInBytes = offset * componentStride;
+ out << convertString << "buffer.Load(loc + " << offsetInBytes << ")),";
+ }
+ out << "};\n";
+ }
+ else
+ {
+ out << " = " << convertString << "buffer.Load"
+ << static_cast<uint32_t>(ssboFunction.type.getNominalSize()) << "(loc));\n";
+ }
+ }
+ else if (ssboFunction.type.isMatrix())
+ {
+ if (ssboFunction.rowMajor)
+ {
+ out << ";";
+ out << " float" << static_cast<uint32_t>(ssboFunction.type.getRows()) << "x"
+ << static_cast<uint32_t>(ssboFunction.type.getCols()) << " tmp_ = {";
+ for (uint8_t rowIndex = 0; rowIndex < ssboFunction.type.getRows(); rowIndex++)
+ {
+ out << "asfloat(buffer.Load" << static_cast<uint32_t>(ssboFunction.type.getCols())
+ << "(loc + " << rowIndex * ssboFunction.matrixStride << ")), ";
+ }
+ out << "};\n";
+ out << " result = transpose(tmp_);\n";
+ }
+ else
+ {
+ out << " = {";
+ for (uint8_t columnIndex = 0; columnIndex < ssboFunction.type.getCols(); columnIndex++)
+ {
+ out << "asfloat(buffer.Load" << static_cast<uint32_t>(ssboFunction.type.getRows())
+ << "(loc + " << columnIndex * ssboFunction.matrixStride << ")), ";
+ }
+ out << "};\n";
+ }
+ }
+ else
+ {
+ // TODO(jiajia.qin@intel.com): Process all possible return types. http://anglebug.com/1951
+ out << ";\n";
+ }
+
+ out << " return result;\n";
+ return;
+}
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOStoreFunctionBody(
+ TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction)
+{
+ size_t bytesPerComponent =
+ gl::VariableComponentSize(gl::VariableComponentType(GLVariableType(ssboFunction.type)));
+ if (ssboFunction.type.isScalar())
+ {
+ size_t offset = ssboFunction.swizzleOffsets[0] * bytesPerComponent;
+ if (ssboFunction.type.getBasicType() == EbtBool)
+ {
+ out << " buffer.Store(loc + " << offset << ", uint(value));\n";
+ }
+ else
+ {
+ out << " buffer.Store(loc + " << offset << ", asuint(value));\n";
+ }
+ }
+ else if (ssboFunction.type.isVector())
+ {
+ out << " uint" << static_cast<uint32_t>(ssboFunction.type.getNominalSize())
+ << " _value;\n";
+ if (ssboFunction.type.getBasicType() == EbtBool)
+ {
+ out << " _value = uint" << static_cast<uint32_t>(ssboFunction.type.getNominalSize())
+ << "(value);\n";
+ }
+ else
+ {
+ out << " _value = asuint(value);\n";
+ }
+
+ if (ssboFunction.rowMajor || !ssboFunction.isDefaultSwizzle)
+ {
+ size_t componentStride = bytesPerComponent;
+ if (ssboFunction.rowMajor)
+ {
+ componentStride = ssboFunction.matrixStride;
+ }
+ const TVector<int> &swizzleOffsets = ssboFunction.swizzleOffsets;
+ for (int index = 0; index < static_cast<int>(swizzleOffsets.size()); index++)
+ {
+ size_t offsetInBytes = swizzleOffsets[index] * componentStride;
+ out << "buffer.Store(loc + " << offsetInBytes << ", _value[" << index << "]);\n";
+ }
+ }
+ else
+ {
+ out << " buffer.Store" << static_cast<uint32_t>(ssboFunction.type.getNominalSize())
+ << "(loc, _value);\n";
+ }
+ }
+ else if (ssboFunction.type.isMatrix())
+ {
+ if (ssboFunction.rowMajor)
+ {
+ out << " float" << static_cast<uint32_t>(ssboFunction.type.getRows()) << "x"
+ << static_cast<uint32_t>(ssboFunction.type.getCols())
+ << " tmp_ = transpose(value);\n";
+ for (uint8_t rowIndex = 0; rowIndex < ssboFunction.type.getRows(); rowIndex++)
+ {
+ out << " buffer.Store" << static_cast<uint32_t>(ssboFunction.type.getCols())
+ << "(loc + " << rowIndex * ssboFunction.matrixStride << ", asuint(tmp_["
+ << static_cast<uint32_t>(rowIndex) << "]));\n";
+ }
+ }
+ else
+ {
+ for (uint8_t columnIndex = 0; columnIndex < ssboFunction.type.getCols(); columnIndex++)
+ {
+ out << " buffer.Store" << static_cast<uint32_t>(ssboFunction.type.getRows())
+ << "(loc + " << columnIndex * ssboFunction.matrixStride << ", asuint(value["
+ << static_cast<uint32_t>(columnIndex) << "]));\n";
+ }
+ }
+ }
+ else
+ {
+ // TODO(jiajia.qin@intel.com): Process all possible return types. http://anglebug.com/1951
+ }
+}
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOLengthFunctionBody(TInfoSinkBase &out,
+ int unsizedArrayStride)
+{
+ out << " uint dim = 0;\n";
+ out << " buffer.GetDimensions(dim);\n";
+ out << " return int((dim - loc)/uint(" << unsizedArrayStride << "));\n";
+}
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOAtomicMemoryFunctionBody(
+ TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction)
+{
+ out << " " << ssboFunction.typeString << " original_value;\n";
+ switch (ssboFunction.method)
+ {
+ case SSBOMethod::ATOMIC_ADD:
+ out << " buffer.InterlockedAdd(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_MIN:
+ out << " buffer.InterlockedMin(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_MAX:
+ out << " buffer.InterlockedMax(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_AND:
+ out << " buffer.InterlockedAnd(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_OR:
+ out << " buffer.InterlockedOr(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_XOR:
+ out << " buffer.InterlockedXor(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_EXCHANGE:
+ out << " buffer.InterlockedExchange(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_COMPSWAP:
+ out << " buffer.InterlockedCompareExchange(loc, compare_value, value, "
+ "original_value);\n";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ out << " return original_value;\n";
+}
+
+bool ShaderStorageBlockFunctionHLSL::ShaderStorageBlockFunction::operator<(
+ const ShaderStorageBlockFunction &rhs) const
+{
+ return functionName < rhs.functionName;
+}
+
+TString ShaderStorageBlockFunctionHLSL::registerShaderStorageBlockFunction(
+ const TType &type,
+ SSBOMethod method,
+ TLayoutBlockStorage storage,
+ bool rowMajor,
+ int matrixStride,
+ int unsizedArrayStride,
+ TIntermSwizzle *swizzleNode)
+{
+ ShaderStorageBlockFunction ssboFunction;
+ ssboFunction.typeString = TypeString(type);
+ ssboFunction.method = method;
+ switch (method)
+ {
+ case SSBOMethod::LOAD:
+ ssboFunction.functionName = "_Load_";
+ break;
+ case SSBOMethod::STORE:
+ ssboFunction.functionName = "_Store_";
+ break;
+ case SSBOMethod::LENGTH:
+ ssboFunction.unsizedArrayStride = unsizedArrayStride;
+ ssboFunction.functionName = "_Length_" + str(unsizedArrayStride);
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_ADD:
+ ssboFunction.functionName = "_ssbo_atomicAdd_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_MIN:
+ ssboFunction.functionName = "_ssbo_atomicMin_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_MAX:
+ ssboFunction.functionName = "_ssbo_atomicMax_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_AND:
+ ssboFunction.functionName = "_ssbo_atomicAnd_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_OR:
+ ssboFunction.functionName = "_ssbo_atomicOr_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_XOR:
+ ssboFunction.functionName = "_ssbo_atomicXor_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_EXCHANGE:
+ ssboFunction.functionName = "_ssbo_atomicExchange_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_COMPSWAP:
+ ssboFunction.functionName = "_ssbo_atomicCompSwap_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ default:
+ UNREACHABLE();
+ }
+
+ ssboFunction.functionName += ssboFunction.typeString;
+ ssboFunction.type = type;
+ if (swizzleNode != nullptr)
+ {
+ ssboFunction.swizzleOffsets = swizzleNode->getSwizzleOffsets();
+ ssboFunction.isDefaultSwizzle = false;
+ }
+ else
+ {
+ if (ssboFunction.type.getNominalSize() > 1)
+ {
+ for (uint8_t index = 0; index < ssboFunction.type.getNominalSize(); index++)
+ {
+ ssboFunction.swizzleOffsets.push_back(index);
+ }
+ }
+ else
+ {
+ ssboFunction.swizzleOffsets.push_back(0);
+ }
+
+ ssboFunction.isDefaultSwizzle = true;
+ }
+ ssboFunction.rowMajor = rowMajor;
+ ssboFunction.matrixStride = matrixStride;
+ ssboFunction.functionName += "_" + TString(getBlockStorageString(storage));
+
+ if (rowMajor)
+ {
+ ssboFunction.functionName += "_rm_";
+ }
+ else
+ {
+ ssboFunction.functionName += "_cm_";
+ }
+
+ for (const int offset : ssboFunction.swizzleOffsets)
+ {
+ switch (offset)
+ {
+ case 0:
+ ssboFunction.functionName += "x";
+ break;
+ case 1:
+ ssboFunction.functionName += "y";
+ break;
+ case 2:
+ ssboFunction.functionName += "z";
+ break;
+ case 3:
+ ssboFunction.functionName += "w";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+}
+
+void ShaderStorageBlockFunctionHLSL::shaderStorageBlockFunctionHeader(TInfoSinkBase &out)
+{
+ for (const ShaderStorageBlockFunction &ssboFunction : mRegisteredShaderStorageBlockFunctions)
+ {
+ switch (ssboFunction.method)
+ {
+ case SSBOMethod::LOAD:
+ {
+ // Function header
+ out << ssboFunction.typeString << " " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc)\n";
+ out << "{\n";
+ OutputSSBOLoadFunctionBody(out, ssboFunction);
+ break;
+ }
+ case SSBOMethod::STORE:
+ {
+ // Function header
+ out << "void " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
+ << " value)\n";
+ out << "{\n";
+ OutputSSBOStoreFunctionBody(out, ssboFunction);
+ break;
+ }
+ case SSBOMethod::LENGTH:
+ {
+ out << "int " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc)\n";
+ out << "{\n";
+ OutputSSBOLengthFunctionBody(out, ssboFunction.unsizedArrayStride);
+ break;
+ }
+ case SSBOMethod::ATOMIC_ADD:
+ case SSBOMethod::ATOMIC_MIN:
+ case SSBOMethod::ATOMIC_MAX:
+ case SSBOMethod::ATOMIC_AND:
+ case SSBOMethod::ATOMIC_OR:
+ case SSBOMethod::ATOMIC_XOR:
+ case SSBOMethod::ATOMIC_EXCHANGE:
+ {
+ out << ssboFunction.typeString << " " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
+ << " value)\n";
+ out << "{\n";
+
+ OutputSSBOAtomicMemoryFunctionBody(out, ssboFunction);
+ break;
+ }
+ case SSBOMethod::ATOMIC_COMPSWAP:
+ {
+ out << ssboFunction.typeString << " " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
+ << " compare_value, " << ssboFunction.typeString << " value)\n";
+ out << "{\n";
+ OutputSSBOAtomicMemoryFunctionBody(out, ssboFunction);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ out << "}\n"
+ "\n";
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.h b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.h
new file mode 100644
index 0000000000..0d3cd0291b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.h
@@ -0,0 +1,94 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ShaderStorageBlockOutputHLSL: A traverser to translate a ssbo_access_chain to an offset of
+// RWByteAddressBuffer.
+// //EOpIndexDirectInterfaceBlock
+// ssbo_variable :=
+// | the name of the SSBO
+// | the name of a variable in an SSBO backed interface block
+
+// // EOpIndexInDirect
+// // EOpIndexDirect
+// ssbo_array_indexing := ssbo_access_chain[expr_no_ssbo]
+
+// // EOpIndexDirectStruct
+// ssbo_structure_access := ssbo_access_chain.identifier
+
+// ssbo_access_chain :=
+// | ssbo_variable
+// | ssbo_array_indexing
+// | ssbo_structure_access
+//
+
+#ifndef COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKFUNCTIONHLSL_H_
+#define COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKFUNCTIONHLSL_H_
+
+#include <set>
+
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+class TIntermSwizzle;
+enum class SSBOMethod
+{
+ LOAD,
+ STORE,
+ LENGTH,
+ ATOMIC_ADD,
+ ATOMIC_MIN,
+ ATOMIC_MAX,
+ ATOMIC_AND,
+ ATOMIC_OR,
+ ATOMIC_XOR,
+ ATOMIC_EXCHANGE,
+ ATOMIC_COMPSWAP
+};
+
+class ShaderStorageBlockFunctionHLSL final : angle::NonCopyable
+{
+ public:
+ TString registerShaderStorageBlockFunction(const TType &type,
+ SSBOMethod method,
+ TLayoutBlockStorage storage,
+ bool rowMajor,
+ int matrixStride,
+ int unsizedArrayStride,
+ TIntermSwizzle *node);
+
+ void shaderStorageBlockFunctionHeader(TInfoSinkBase &out);
+
+ private:
+ struct ShaderStorageBlockFunction
+ {
+ bool operator<(const ShaderStorageBlockFunction &rhs) const;
+ TString functionName;
+ TString typeString;
+ SSBOMethod method;
+ TType type;
+ bool rowMajor;
+ int matrixStride;
+ int unsizedArrayStride;
+ TVector<int> swizzleOffsets;
+ bool isDefaultSwizzle;
+ };
+
+ static void OutputSSBOLoadFunctionBody(TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction);
+ static void OutputSSBOStoreFunctionBody(TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction);
+ static void OutputSSBOLengthFunctionBody(TInfoSinkBase &out, int unsizedArrayStride);
+ static void OutputSSBOAtomicMemoryFunctionBody(TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction);
+ using ShaderStorageBlockFunctionSet = std::set<ShaderStorageBlockFunction>;
+ ShaderStorageBlockFunctionSet mRegisteredShaderStorageBlockFunctions;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKFUNCTIONHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.cpp
new file mode 100644
index 0000000000..2ff01e439e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.cpp
@@ -0,0 +1,667 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ShaderStorageBlockOutputHLSL: A traverser to translate a ssbo_access_chain to an offset of
+// RWByteAddressBuffer.
+// //EOpIndexDirectInterfaceBlock
+// ssbo_variable :=
+// | the name of the SSBO
+// | the name of a variable in an SSBO backed interface block
+
+// // EOpIndexInDirect
+// // EOpIndexDirect
+// ssbo_array_indexing := ssbo_access_chain[expr_no_ssbo]
+
+// // EOpIndexDirectStruct
+// ssbo_structure_access := ssbo_access_chain.identifier
+
+// ssbo_access_chain :=
+// | ssbo_variable
+// | ssbo_array_indexing
+// | ssbo_structure_access
+//
+
+#include "compiler/translator/ShaderStorageBlockOutputHLSL.h"
+
+#include "compiler/translator/ResourcesHLSL.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const char kShaderStorageDeclarationString[] =
+ "// @@ SHADER STORAGE DECLARATION STRING @@";
+
+void GetBlockLayoutInfo(TIntermTyped *node,
+ bool rowMajorAlreadyAssigned,
+ TLayoutBlockStorage *storage,
+ bool *rowMajor)
+{
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ return GetBlockLayoutInfo(swizzleNode->getOperand(), rowMajorAlreadyAssigned, storage,
+ rowMajor);
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirectInterfaceBlock:
+ {
+ // The column_major/row_major qualifier of a field member overrides the interface
+ // block's row_major/column_major. So we can assign rowMajor here and don't need to
+ // assign it again. But we still need to call recursively to get the storage's
+ // value.
+ const TType &type = node->getType();
+ *rowMajor = type.getLayoutQualifier().matrixPacking == EmpRowMajor;
+ return GetBlockLayoutInfo(binaryNode->getLeft(), true, storage, rowMajor);
+ }
+ case EOpIndexIndirect:
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ return GetBlockLayoutInfo(binaryNode->getLeft(), rowMajorAlreadyAssigned, storage,
+ rowMajor);
+ default:
+ UNREACHABLE();
+ return;
+ }
+ }
+
+ const TType &type = node->getType();
+ ASSERT(type.getQualifier() == EvqBuffer);
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ ASSERT(interfaceBlock);
+ *storage = interfaceBlock->blockStorage();
+ // If the block doesn't have an instance name, rowMajorAlreadyAssigned will be false. In
+ // this situation, we still need to set rowMajor's value.
+ if (!rowMajorAlreadyAssigned)
+ {
+ *rowMajor = type.getLayoutQualifier().matrixPacking == EmpRowMajor;
+ }
+}
+
+// It's possible that the current type has lost the original layout information. So we should pass
+// the right layout information to GetBlockMemberInfoByType.
+const BlockMemberInfo GetBlockMemberInfoByType(const TType &type,
+ TLayoutBlockStorage storage,
+ bool rowMajor)
+{
+ sh::Std140BlockEncoder std140Encoder;
+ sh::Std430BlockEncoder std430Encoder;
+ sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false);
+ sh::BlockLayoutEncoder *encoder = nullptr;
+
+ if (storage == EbsStd140)
+ {
+ encoder = &std140Encoder;
+ }
+ else if (storage == EbsStd430)
+ {
+ encoder = &std430Encoder;
+ }
+ else
+ {
+ encoder = &hlslEncoder;
+ }
+
+ std::vector<unsigned int> arraySizes;
+ const TSpan<const unsigned int> &typeArraySizes = type.getArraySizes();
+ if (!typeArraySizes.empty())
+ {
+ arraySizes.assign(typeArraySizes.begin(), typeArraySizes.end());
+ }
+ return encoder->encodeType(GLVariableType(type), arraySizes, rowMajor);
+}
+
+const TField *GetFieldMemberInShaderStorageBlock(const TInterfaceBlock *interfaceBlock,
+ const ImmutableString &variableName)
+{
+ for (const TField *field : interfaceBlock->fields())
+ {
+ if (field->name() == variableName)
+ {
+ return field;
+ }
+ }
+ return nullptr;
+}
+
+const InterfaceBlock *FindInterfaceBlock(const TInterfaceBlock *needle,
+ const std::vector<InterfaceBlock> &haystack)
+{
+ for (const InterfaceBlock &block : haystack)
+ {
+ if (strcmp(block.name.c_str(), needle->name().data()) == 0)
+ {
+ ASSERT(block.fields.size() == needle->fields().size());
+ return &block;
+ }
+ }
+
+ UNREACHABLE();
+ return nullptr;
+}
+
+std::string StripArrayIndices(const std::string &nameIn)
+{
+ std::string name = nameIn;
+ size_t pos = name.find('[');
+ while (pos != std::string::npos)
+ {
+ size_t closePos = name.find(']', pos);
+ ASSERT(closePos != std::string::npos);
+ name.erase(pos, closePos - pos + 1);
+ pos = name.find('[', pos);
+ }
+ ASSERT(name.find(']') == std::string::npos);
+ return name;
+}
+
+// Does not include any array indices.
+void MapVariableToField(const ShaderVariable &variable,
+ const TField *field,
+ std::string currentName,
+ ShaderVarToFieldMap *shaderVarToFieldMap)
+{
+ ASSERT((field->type()->getStruct() == nullptr) == variable.fields.empty());
+ (*shaderVarToFieldMap)[currentName] = field;
+
+ if (!variable.fields.empty())
+ {
+ const TStructure *subStruct = field->type()->getStruct();
+ ASSERT(variable.fields.size() == subStruct->fields().size());
+
+ for (size_t index = 0; index < variable.fields.size(); ++index)
+ {
+ const TField *subField = subStruct->fields()[index];
+ const ShaderVariable &subVariable = variable.fields[index];
+ std::string subName = currentName + "." + subVariable.name;
+ MapVariableToField(subVariable, subField, subName, shaderVarToFieldMap);
+ }
+ }
+}
+
+class BlockInfoVisitor final : public BlockEncoderVisitor
+{
+ public:
+ BlockInfoVisitor(const std::string &prefix,
+ TLayoutBlockStorage storage,
+ const ShaderVarToFieldMap &shaderVarToFieldMap,
+ BlockMemberInfoMap *blockInfoOut)
+ : BlockEncoderVisitor(prefix, "", getEncoder(storage)),
+ mShaderVarToFieldMap(shaderVarToFieldMap),
+ mBlockInfoOut(blockInfoOut),
+ mHLSLEncoder(HLSLBlockEncoder::ENCODE_PACKED, false),
+ mStorage(storage)
+ {}
+
+ BlockLayoutEncoder *getEncoder(TLayoutBlockStorage storage)
+ {
+ switch (storage)
+ {
+ case EbsStd140:
+ return &mStd140Encoder;
+ case EbsStd430:
+ return &mStd430Encoder;
+ default:
+ return &mHLSLEncoder;
+ }
+ }
+
+ void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override
+ {
+ BlockEncoderVisitor::enterStructAccess(structVar, isRowMajor);
+
+ std::string variableName = StripArrayIndices(collapseNameStack());
+
+ // Remove the trailing "."
+ variableName.pop_back();
+
+ BlockInfoVisitor childVisitor(variableName, mStorage, mShaderVarToFieldMap, mBlockInfoOut);
+ childVisitor.getEncoder(mStorage)->enterAggregateType(structVar);
+ TraverseShaderVariables(structVar.fields, isRowMajor, &childVisitor);
+ childVisitor.getEncoder(mStorage)->exitAggregateType(structVar);
+
+ int offset = static_cast<int>(getEncoder(mStorage)->getCurrentOffset());
+ int arrayStride = static_cast<int>(childVisitor.getEncoder(mStorage)->getCurrentOffset());
+
+ auto iter = mShaderVarToFieldMap.find(variableName);
+ if (iter == mShaderVarToFieldMap.end())
+ return;
+
+ const TField *structField = iter->second;
+ if (mBlockInfoOut->count(structField) == 0)
+ {
+ mBlockInfoOut->emplace(structField, BlockMemberInfo(offset, arrayStride, -1, false));
+ }
+ }
+
+ void encodeVariable(const ShaderVariable &variable,
+ const BlockMemberInfo &variableInfo,
+ const std::string &name,
+ const std::string &mappedName) override
+ {
+ auto iter = mShaderVarToFieldMap.find(StripArrayIndices(name));
+ if (iter == mShaderVarToFieldMap.end())
+ return;
+
+ const TField *field = iter->second;
+ if (mBlockInfoOut->count(field) == 0)
+ {
+ mBlockInfoOut->emplace(field, variableInfo);
+ }
+ }
+
+ private:
+ const ShaderVarToFieldMap &mShaderVarToFieldMap;
+ BlockMemberInfoMap *mBlockInfoOut;
+ Std140BlockEncoder mStd140Encoder;
+ Std430BlockEncoder mStd430Encoder;
+ HLSLBlockEncoder mHLSLEncoder;
+ TLayoutBlockStorage mStorage;
+};
+
+void GetShaderStorageBlockMembersInfo(const TInterfaceBlock *interfaceBlock,
+ const std::vector<InterfaceBlock> &shaderStorageBlocks,
+ BlockMemberInfoMap *blockInfoOut)
+{
+ // Find the sh::InterfaceBlock.
+ const InterfaceBlock *block = FindInterfaceBlock(interfaceBlock, shaderStorageBlocks);
+ ASSERT(block);
+
+ // Map ShaderVariable to TField.
+ ShaderVarToFieldMap shaderVarToFieldMap;
+ for (size_t index = 0; index < block->fields.size(); ++index)
+ {
+ const TField *field = interfaceBlock->fields()[index];
+ const ShaderVariable &variable = block->fields[index];
+ MapVariableToField(variable, field, variable.name, &shaderVarToFieldMap);
+ }
+
+ BlockInfoVisitor visitor("", interfaceBlock->blockStorage(), shaderVarToFieldMap, blockInfoOut);
+ TraverseShaderVariables(block->fields, false, &visitor);
+}
+
+TIntermTyped *Mul(TIntermTyped *left, TIntermTyped *right)
+{
+ return left && right ? new TIntermBinary(EOpMul, left, right) : nullptr;
+}
+
+TIntermTyped *Add(TIntermTyped *left, TIntermTyped *right)
+{
+ return left ? right ? new TIntermBinary(EOpAdd, left, right) : left : right;
+}
+
+} // anonymous namespace
+
+ShaderStorageBlockOutputHLSL::ShaderStorageBlockOutputHLSL(
+ OutputHLSL *outputHLSL,
+ ResourcesHLSL *resourcesHLSL,
+ const std::vector<InterfaceBlock> &shaderStorageBlocks)
+ : mOutputHLSL(outputHLSL),
+ mResourcesHLSL(resourcesHLSL),
+ mShaderStorageBlocks(shaderStorageBlocks)
+{
+ mSSBOFunctionHLSL = new ShaderStorageBlockFunctionHLSL;
+}
+
+ShaderStorageBlockOutputHLSL::~ShaderStorageBlockOutputHLSL()
+{
+ SafeDelete(mSSBOFunctionHLSL);
+}
+
+void ShaderStorageBlockOutputHLSL::outputStoreFunctionCallPrefix(TIntermTyped *node)
+{
+ traverseSSBOAccess(node, SSBOMethod::STORE);
+}
+
+void ShaderStorageBlockOutputHLSL::outputLoadFunctionCall(TIntermTyped *node)
+{
+ traverseSSBOAccess(node, SSBOMethod::LOAD);
+ mOutputHLSL->getInfoSink() << ")";
+}
+
+void ShaderStorageBlockOutputHLSL::outputLengthFunctionCall(TIntermTyped *node)
+{
+ traverseSSBOAccess(node, SSBOMethod::LENGTH);
+ mOutputHLSL->getInfoSink() << ")";
+}
+
+void ShaderStorageBlockOutputHLSL::outputAtomicMemoryFunctionCallPrefix(TIntermTyped *node,
+ TOperator op)
+{
+ switch (op)
+ {
+ case EOpAtomicAdd:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_ADD);
+ break;
+ case EOpAtomicMin:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_MIN);
+ break;
+ case EOpAtomicMax:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_MAX);
+ break;
+ case EOpAtomicAnd:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_AND);
+ break;
+ case EOpAtomicOr:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_OR);
+ break;
+ case EOpAtomicXor:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_XOR);
+ break;
+ case EOpAtomicExchange:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_EXCHANGE);
+ break;
+ case EOpAtomicCompSwap:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_COMPSWAP);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+// Note that we must calculate the matrix stride here instead of ShaderStorageBlockFunctionHLSL.
+// It's because that if the current node's type is a vector which comes from a matrix, we will
+// lose the matrix type info once we enter ShaderStorageBlockFunctionHLSL.
+int ShaderStorageBlockOutputHLSL::getMatrixStride(TIntermTyped *node,
+ TLayoutBlockStorage storage,
+ bool rowMajor,
+ bool *isRowMajorMatrix) const
+{
+ if (node->getType().isMatrix())
+ {
+ *isRowMajorMatrix = rowMajor;
+ return GetBlockMemberInfoByType(node->getType(), storage, rowMajor).matrixStride;
+ }
+
+ if (node->getType().isVector())
+ {
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ return getMatrixStride(binaryNode->getLeft(), storage, rowMajor, isRowMajorMatrix);
+ }
+ else
+ {
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ return getMatrixStride(swizzleNode->getOperand(), storage, rowMajor,
+ isRowMajorMatrix);
+ }
+ }
+ }
+ return 0;
+}
+
+void ShaderStorageBlockOutputHLSL::collectShaderStorageBlocks(TIntermTyped *node)
+{
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ return collectShaderStorageBlocks(swizzleNode->getOperand());
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirectInterfaceBlock:
+ case EOpIndexIndirect:
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ return collectShaderStorageBlocks(binaryNode->getLeft());
+ default:
+ UNREACHABLE();
+ return;
+ }
+ }
+
+ const TIntermSymbol *symbolNode = node->getAsSymbolNode();
+ const TType &type = symbolNode->getType();
+ ASSERT(type.getQualifier() == EvqBuffer);
+ const TVariable &variable = symbolNode->variable();
+
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ ASSERT(interfaceBlock);
+ if (mReferencedShaderStorageBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ const TVariable *instanceVariable = nullptr;
+ if (type.isInterfaceBlock())
+ {
+ instanceVariable = &variable;
+ }
+ mReferencedShaderStorageBlocks[interfaceBlock->uniqueId().get()] =
+ new TReferencedBlock(interfaceBlock, instanceVariable);
+ GetShaderStorageBlockMembersInfo(interfaceBlock, mShaderStorageBlocks,
+ &mBlockMemberInfoMap);
+ }
+}
+
+void ShaderStorageBlockOutputHLSL::traverseSSBOAccess(TIntermTyped *node, SSBOMethod method)
+{
+ // TODO: Merge collectShaderStorageBlocks and GetBlockLayoutInfo to simplify the code.
+ collectShaderStorageBlocks(node);
+
+ // Note that we don't have correct BlockMemberInfo from mBlockMemberInfoMap at the current
+ // point. But we must use those information to generate the right function name. So here we have
+ // to calculate them again.
+ TLayoutBlockStorage storage;
+ bool rowMajor;
+ GetBlockLayoutInfo(node, false, &storage, &rowMajor);
+ int unsizedArrayStride = 0;
+ if (node->getType().isUnsizedArray())
+ {
+ // The unsized array member must be the last member of a shader storage block.
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ binaryNode->getLeft()->getType().getInterfaceBlock();
+ ASSERT(interfaceBlock);
+ const TIntermConstantUnion *index = binaryNode->getRight()->getAsConstantUnion();
+ const TField *field = interfaceBlock->fields()[index->getIConst(0)];
+ auto fieldInfoIter = mBlockMemberInfoMap.find(field);
+ ASSERT(fieldInfoIter != mBlockMemberInfoMap.end());
+ unsizedArrayStride = fieldInfoIter->second.arrayStride;
+ }
+ else
+ {
+ const TIntermSymbol *symbolNode = node->getAsSymbolNode();
+ const TVariable &variable = symbolNode->variable();
+ const TInterfaceBlock *interfaceBlock = symbolNode->getType().getInterfaceBlock();
+ ASSERT(interfaceBlock);
+ const TField *field =
+ GetFieldMemberInShaderStorageBlock(interfaceBlock, variable.name());
+ auto fieldInfoIter = mBlockMemberInfoMap.find(field);
+ ASSERT(fieldInfoIter != mBlockMemberInfoMap.end());
+ unsizedArrayStride = fieldInfoIter->second.arrayStride;
+ }
+ }
+ bool isRowMajorMatrix = false;
+ int matrixStride = getMatrixStride(node, storage, rowMajor, &isRowMajorMatrix);
+
+ const TString &functionName = mSSBOFunctionHLSL->registerShaderStorageBlockFunction(
+ node->getType(), method, storage, isRowMajorMatrix, matrixStride, unsizedArrayStride,
+ node->getAsSwizzleNode());
+ TInfoSinkBase &out = mOutputHLSL->getInfoSink();
+ out << functionName;
+ out << "(";
+ BlockMemberInfo blockMemberInfo;
+ TIntermNode *loc = traverseNode(out, node, &blockMemberInfo);
+ out << ", ";
+ loc->traverse(mOutputHLSL);
+}
+
+void ShaderStorageBlockOutputHLSL::writeShaderStorageBlocksHeader(GLenum shaderType,
+ TInfoSinkBase &out) const
+{
+ if (mReferencedShaderStorageBlocks.empty())
+ {
+ return;
+ }
+
+ mResourcesHLSL->allocateShaderStorageBlockRegisters(mReferencedShaderStorageBlocks);
+ out << "// Shader Storage Blocks\n\n";
+ if (shaderType == GL_COMPUTE_SHADER)
+ {
+ out << mResourcesHLSL->shaderStorageBlocksHeader(mReferencedShaderStorageBlocks);
+ }
+ else
+ {
+ out << kShaderStorageDeclarationString << "\n";
+ }
+ mSSBOFunctionHLSL->shaderStorageBlockFunctionHeader(out);
+}
+
+TIntermTyped *ShaderStorageBlockOutputHLSL::traverseNode(TInfoSinkBase &out,
+ TIntermTyped *node,
+ BlockMemberInfo *blockMemberInfo)
+{
+ if (TIntermSymbol *symbolNode = node->getAsSymbolNode())
+ {
+ const TVariable &variable = symbolNode->variable();
+ const TType &type = variable.getType();
+ if (type.isInterfaceBlock())
+ {
+ out << DecorateVariableIfNeeded(variable);
+ }
+ else
+ {
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ out << Decorate(interfaceBlock->name());
+ const TField *field =
+ GetFieldMemberInShaderStorageBlock(interfaceBlock, variable.name());
+ return createFieldOffset(field, blockMemberInfo);
+ }
+ }
+ else if (TIntermSwizzle *swizzleNode = node->getAsSwizzleNode())
+ {
+ return traverseNode(out, swizzleNode->getOperand(), blockMemberInfo);
+ }
+ else if (TIntermBinary *binaryNode = node->getAsBinaryNode())
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirect:
+ {
+ const TType &leftType = binaryNode->getLeft()->getType();
+ if (leftType.isInterfaceBlock())
+ {
+ ASSERT(leftType.getQualifier() == EvqBuffer);
+ TIntermSymbol *instanceArraySymbol = binaryNode->getLeft()->getAsSymbolNode();
+
+ const int arrayIndex =
+ binaryNode->getRight()->getAsConstantUnion()->getIConst(0);
+ out << mResourcesHLSL->InterfaceBlockInstanceString(
+ instanceArraySymbol->getName(), arrayIndex);
+ }
+ else
+ {
+ return writeEOpIndexDirectOrIndirectOutput(out, binaryNode, blockMemberInfo);
+ }
+ break;
+ }
+ case EOpIndexIndirect:
+ {
+ // We do not currently support indirect references to interface blocks
+ ASSERT(binaryNode->getLeft()->getBasicType() != EbtInterfaceBlock);
+ return writeEOpIndexDirectOrIndirectOutput(out, binaryNode, blockMemberInfo);
+ }
+ case EOpIndexDirectStruct:
+ {
+ // We do not currently support direct references to interface blocks
+ ASSERT(binaryNode->getLeft()->getBasicType() != EbtInterfaceBlock);
+ TIntermTyped *left = traverseNode(out, binaryNode->getLeft(), blockMemberInfo);
+ const TStructure *structure = binaryNode->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index = binaryNode->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+ return Add(createFieldOffset(field, blockMemberInfo), left);
+ }
+ case EOpIndexDirectInterfaceBlock:
+ {
+ ASSERT(IsInShaderStorageBlock(binaryNode->getLeft()));
+ traverseNode(out, binaryNode->getLeft(), blockMemberInfo);
+ const TInterfaceBlock *interfaceBlock =
+ binaryNode->getLeft()->getType().getInterfaceBlock();
+ const TIntermConstantUnion *index = binaryNode->getRight()->getAsConstantUnion();
+ const TField *field = interfaceBlock->fields()[index->getIConst(0)];
+ return createFieldOffset(field, blockMemberInfo);
+ }
+ default:
+ return nullptr;
+ }
+ }
+ return nullptr;
+}
+
+TIntermTyped *ShaderStorageBlockOutputHLSL::writeEOpIndexDirectOrIndirectOutput(
+ TInfoSinkBase &out,
+ TIntermBinary *node,
+ BlockMemberInfo *blockMemberInfo)
+{
+ ASSERT(IsInShaderStorageBlock(node->getLeft()));
+ TIntermTyped *left = traverseNode(out, node->getLeft(), blockMemberInfo);
+ TIntermTyped *right = node->getRight()->deepCopy();
+ const TType &type = node->getLeft()->getType();
+ TLayoutBlockStorage storage;
+ bool rowMajor;
+ GetBlockLayoutInfo(node, false, &storage, &rowMajor);
+
+ if (type.isArray())
+ {
+ const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
+ for (unsigned int i = 0; i < arraySizes.size() - 1; i++)
+ {
+ right = Mul(CreateUIntNode(arraySizes[i]), right);
+ }
+ right = Mul(CreateUIntNode(blockMemberInfo->arrayStride), right);
+ }
+ else if (type.isMatrix())
+ {
+ if (rowMajor)
+ {
+ right = Mul(CreateUIntNode(BlockLayoutEncoder::kBytesPerComponent), right);
+ }
+ else
+ {
+ right = Mul(CreateUIntNode(blockMemberInfo->matrixStride), right);
+ }
+ }
+ else if (type.isVector())
+ {
+ if (blockMemberInfo->isRowMajorMatrix)
+ {
+ right = Mul(CreateUIntNode(blockMemberInfo->matrixStride), right);
+ }
+ else
+ {
+ right = Mul(CreateUIntNode(BlockLayoutEncoder::kBytesPerComponent), right);
+ }
+ }
+ return Add(left, right);
+}
+
+TIntermTyped *ShaderStorageBlockOutputHLSL::createFieldOffset(const TField *field,
+ BlockMemberInfo *blockMemberInfo)
+{
+ auto fieldInfoIter = mBlockMemberInfoMap.find(field);
+ ASSERT(fieldInfoIter != mBlockMemberInfoMap.end());
+ *blockMemberInfo = fieldInfoIter->second;
+ return CreateUIntNode(blockMemberInfo->offset);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.h b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.h
new file mode 100644
index 0000000000..2acf06a0ea
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.h
@@ -0,0 +1,86 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ShaderStorageBlockOutputHLSL: A traverser to translate a buffer variable of shader storage block
+// to an offset of RWByteAddressBuffer.
+//
+
+#ifndef COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKOUTPUTHLSL_H_
+#define COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKOUTPUTHLSL_H_
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/ShaderStorageBlockFunctionHLSL.h"
+#include "compiler/translator/blocklayout.h"
+
+namespace sh
+{
+class ResourcesHLSL;
+class OutputHLSL;
+class TSymbolTable;
+
+struct TReferencedBlock : angle::NonCopyable
+{
+ POOL_ALLOCATOR_NEW_DELETE
+ TReferencedBlock(const TInterfaceBlock *block, const TVariable *instanceVariable);
+ const TInterfaceBlock *block;
+ const TVariable *instanceVariable; // May be nullptr if the block is not instanced.
+};
+
+// Maps from uniqueId to a variable.
+using ReferencedInterfaceBlocks = std::map<int, const TReferencedBlock *>;
+
+// Used to save shader storage block field member information.
+using BlockMemberInfoMap = std::map<const TField *, BlockMemberInfo>;
+
+using ShaderVarToFieldMap = std::map<std::string, const TField *>;
+
+class ShaderStorageBlockOutputHLSL
+{
+ public:
+ ShaderStorageBlockOutputHLSL(OutputHLSL *outputHLSL,
+ ResourcesHLSL *resourcesHLSL,
+ const std::vector<InterfaceBlock> &shaderStorageBlocks);
+
+ ~ShaderStorageBlockOutputHLSL();
+
+ // This writes part of the function call to store a value to a SSBO to the output stream. After
+ // calling this, ", <stored value>)" should be written to the output stream to complete the
+ // function call.
+ void outputStoreFunctionCallPrefix(TIntermTyped *node);
+ // This writes the function call to load a SSBO value to the output stream.
+ void outputLoadFunctionCall(TIntermTyped *node);
+ // This writes the function call to get the lengh of unsized array member of SSBO.
+ void outputLengthFunctionCall(TIntermTyped *node);
+ // Writes the atomic memory function calls for SSBO.
+ void outputAtomicMemoryFunctionCallPrefix(TIntermTyped *node, TOperator op);
+
+ void writeShaderStorageBlocksHeader(GLenum shaderType, TInfoSinkBase &out) const;
+
+ private:
+ void traverseSSBOAccess(TIntermTyped *node, SSBOMethod method);
+ TIntermTyped *traverseNode(TInfoSinkBase &out,
+ TIntermTyped *node,
+ BlockMemberInfo *blockMemberInfo);
+ int getMatrixStride(TIntermTyped *node,
+ TLayoutBlockStorage storage,
+ bool rowMajor,
+ bool *isRowMajor) const;
+ TIntermTyped *writeEOpIndexDirectOrIndirectOutput(TInfoSinkBase &out,
+ TIntermBinary *node,
+ BlockMemberInfo *blockMemberInfo);
+ // Common part in dot operations.
+ TIntermTyped *createFieldOffset(const TField *field, BlockMemberInfo *blockMemberInfo);
+ void collectShaderStorageBlocks(TIntermTyped *node);
+ OutputHLSL *mOutputHLSL;
+ ShaderStorageBlockFunctionHLSL *mSSBOFunctionHLSL;
+ ResourcesHLSL *mResourcesHLSL;
+ ReferencedInterfaceBlocks mReferencedShaderStorageBlocks;
+
+ BlockMemberInfoMap mBlockMemberInfoMap;
+ const std::vector<InterfaceBlock> &mShaderStorageBlocks;
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKOUTPUTHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp b/gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp
new file mode 100644
index 0000000000..85d87e2be4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp
@@ -0,0 +1,625 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ShaderVars.cpp:
+// Methods for GL variable types (varyings, uniforms, etc)
+//
+
+#include <GLSLANG/ShaderLang.h>
+
+#include "common/debug.h"
+#include "common/utilities.h"
+
+namespace sh
+{
+
+namespace
+{
+
+InterpolationType GetNonAuxiliaryInterpolationType(InterpolationType interpolation)
+{
+ return (interpolation == INTERPOLATION_CENTROID ? INTERPOLATION_SMOOTH : interpolation);
+}
+} // namespace
+// The ES 3.0 spec is not clear on this point, but the ES 3.1 spec, and discussion
+// on Khronos.org, clarifies that a smooth/flat mismatch produces a link error,
+// but auxiliary qualifier mismatch (centroid) does not.
+bool InterpolationTypesMatch(InterpolationType a, InterpolationType b)
+{
+ return (GetNonAuxiliaryInterpolationType(a) == GetNonAuxiliaryInterpolationType(b));
+}
+
+ShaderVariable::ShaderVariable() : ShaderVariable(GL_NONE) {}
+
+ShaderVariable::ShaderVariable(GLenum typeIn)
+ : type(typeIn),
+ precision(0),
+ staticUse(false),
+ active(false),
+ isRowMajorLayout(false),
+ location(-1),
+ hasImplicitLocation(false),
+ binding(-1),
+ imageUnitFormat(GL_NONE),
+ offset(-1),
+ rasterOrdered(false),
+ readonly(false),
+ writeonly(false),
+ isFragmentInOut(false),
+ index(-1),
+ yuv(false),
+ interpolation(INTERPOLATION_SMOOTH),
+ isInvariant(false),
+ isShaderIOBlock(false),
+ isPatch(false),
+ texelFetchStaticUse(false),
+ flattenedOffsetInParentArrays(-1)
+{}
+
+ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn) : ShaderVariable(typeIn)
+{
+ ASSERT(arraySizeIn != 0);
+ arraySizes.push_back(arraySizeIn);
+}
+
+ShaderVariable::~ShaderVariable() {}
+
+ShaderVariable::ShaderVariable(const ShaderVariable &other)
+ : type(other.type),
+ precision(other.precision),
+ name(other.name),
+ mappedName(other.mappedName),
+ arraySizes(other.arraySizes),
+ staticUse(other.staticUse),
+ active(other.active),
+ fields(other.fields),
+ structOrBlockName(other.structOrBlockName),
+ mappedStructOrBlockName(other.mappedStructOrBlockName),
+ isRowMajorLayout(other.isRowMajorLayout),
+ location(other.location),
+ hasImplicitLocation(other.hasImplicitLocation),
+ binding(other.binding),
+ imageUnitFormat(other.imageUnitFormat),
+ offset(other.offset),
+ rasterOrdered(other.rasterOrdered),
+ readonly(other.readonly),
+ writeonly(other.writeonly),
+ isFragmentInOut(other.isFragmentInOut),
+ index(other.index),
+ yuv(other.yuv),
+ interpolation(other.interpolation),
+ isInvariant(other.isInvariant),
+ isShaderIOBlock(other.isShaderIOBlock),
+ isPatch(other.isPatch),
+ texelFetchStaticUse(other.texelFetchStaticUse),
+ flattenedOffsetInParentArrays(other.flattenedOffsetInParentArrays)
+{}
+
+ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
+{
+ type = other.type;
+ precision = other.precision;
+ name = other.name;
+ mappedName = other.mappedName;
+ arraySizes = other.arraySizes;
+ staticUse = other.staticUse;
+ active = other.active;
+ fields = other.fields;
+ structOrBlockName = other.structOrBlockName;
+ mappedStructOrBlockName = other.mappedStructOrBlockName;
+ isRowMajorLayout = other.isRowMajorLayout;
+ flattenedOffsetInParentArrays = other.flattenedOffsetInParentArrays;
+ location = other.location;
+ hasImplicitLocation = other.hasImplicitLocation;
+ binding = other.binding;
+ imageUnitFormat = other.imageUnitFormat;
+ offset = other.offset;
+ rasterOrdered = other.rasterOrdered;
+ readonly = other.readonly;
+ writeonly = other.writeonly;
+ isFragmentInOut = other.isFragmentInOut;
+ index = other.index;
+ yuv = other.yuv;
+ interpolation = other.interpolation;
+ isInvariant = other.isInvariant;
+ isShaderIOBlock = other.isShaderIOBlock;
+ isPatch = other.isPatch;
+ texelFetchStaticUse = other.texelFetchStaticUse;
+ return *this;
+}
+
+bool ShaderVariable::operator==(const ShaderVariable &other) const
+{
+ if (type != other.type || precision != other.precision || name != other.name ||
+ mappedName != other.mappedName || arraySizes != other.arraySizes ||
+ staticUse != other.staticUse || active != other.active ||
+ fields.size() != other.fields.size() || structOrBlockName != other.structOrBlockName ||
+ mappedStructOrBlockName != other.mappedStructOrBlockName ||
+ isRowMajorLayout != other.isRowMajorLayout || location != other.location ||
+ hasImplicitLocation != other.hasImplicitLocation || binding != other.binding ||
+ imageUnitFormat != other.imageUnitFormat || offset != other.offset ||
+ rasterOrdered != other.rasterOrdered || readonly != other.readonly ||
+ writeonly != other.writeonly || index != other.index || yuv != other.yuv ||
+ interpolation != other.interpolation || isInvariant != other.isInvariant ||
+ isShaderIOBlock != other.isShaderIOBlock || isPatch != other.isPatch ||
+ texelFetchStaticUse != other.texelFetchStaticUse ||
+ isFragmentInOut != other.isFragmentInOut)
+ {
+ return false;
+ }
+ for (size_t ii = 0; ii < fields.size(); ++ii)
+ {
+ if (fields[ii] != other.fields[ii])
+ return false;
+ }
+ return true;
+}
+
+void ShaderVariable::setArraySize(unsigned int size)
+{
+ arraySizes.clear();
+ if (size != 0)
+ {
+ arraySizes.push_back(size);
+ }
+}
+
+unsigned int ShaderVariable::getInnerArraySizeProduct() const
+{
+ return gl::InnerArraySizeProduct(arraySizes);
+}
+
+unsigned int ShaderVariable::getArraySizeProduct() const
+{
+ return gl::ArraySizeProduct(arraySizes);
+}
+
+void ShaderVariable::indexIntoArray(unsigned int arrayIndex)
+{
+ ASSERT(isArray());
+ flattenedOffsetInParentArrays = arrayIndex + getOutermostArraySize() * parentArrayIndex();
+ arraySizes.pop_back();
+}
+
+unsigned int ShaderVariable::getNestedArraySize(unsigned int arrayNestingIndex) const
+{
+ ASSERT(arraySizes.size() > arrayNestingIndex);
+ unsigned int arraySize = arraySizes[arraySizes.size() - 1u - arrayNestingIndex];
+
+ if (arraySize == 0)
+ {
+ // Unsized array, so give it at least 1 entry
+ arraySize = 1;
+ }
+
+ return arraySize;
+}
+
+unsigned int ShaderVariable::getBasicTypeElementCount() const
+{
+ // GLES 3.1 Nov 2016 section 7.3.1.1 page 77 specifies that a separate entry should be generated
+ // for each array element when dealing with an array of arrays or an array of structs.
+ ASSERT(!isArrayOfArrays());
+ ASSERT(!isStruct() || !isArray());
+
+ // GLES 3.1 Nov 2016 page 82.
+ if (isArray())
+ {
+ return getOutermostArraySize();
+ }
+ return 1u;
+}
+
+unsigned int ShaderVariable::getExternalSize() const
+{
+ unsigned int memorySize = 0;
+
+ if (isStruct())
+ {
+ // Have a structure, need to compute the structure size.
+ for (const auto &field : fields)
+ {
+ memorySize += field.getExternalSize();
+ }
+ }
+ else
+ {
+ memorySize += gl::VariableExternalSize(type);
+ }
+
+ // multiply by array size to get total memory size of this variable / struct.
+ memorySize *= getArraySizeProduct();
+
+ return memorySize;
+}
+
+bool ShaderVariable::findInfoByMappedName(const std::string &mappedFullName,
+ const ShaderVariable **leafVar,
+ std::string *originalFullName) const
+{
+ ASSERT(leafVar && originalFullName);
+ // There are three cases:
+ // 1) the top variable is of struct type;
+ // 2) the top variable is an array;
+ // 3) otherwise.
+ size_t pos = mappedFullName.find_first_of(".[");
+
+ if (pos == std::string::npos)
+ {
+ // Case 3.
+ if (mappedFullName != this->mappedName)
+ return false;
+ *originalFullName = this->name;
+ *leafVar = this;
+ return true;
+ }
+ else
+ {
+ std::string topName = mappedFullName.substr(0, pos);
+ if (topName != this->mappedName)
+ return false;
+ std::string originalName = this->name;
+ std::string remaining;
+ if (mappedFullName[pos] == '[')
+ {
+ // Case 2.
+ size_t closePos = mappedFullName.find_first_of(']');
+ if (closePos < pos || closePos == std::string::npos)
+ return false;
+ // Append '[index]'.
+ originalName += mappedFullName.substr(pos, closePos - pos + 1);
+ if (closePos + 1 == mappedFullName.size())
+ {
+ *originalFullName = originalName;
+ *leafVar = this;
+ return true;
+ }
+ else
+ {
+ // In the form of 'a[0].b', so after ']', '.' is expected.
+ if (mappedFullName[closePos + 1] != '.')
+ return false;
+ remaining = mappedFullName.substr(closePos + 2); // Skip "]."
+ }
+ }
+ else
+ {
+ // Case 1.
+ remaining = mappedFullName.substr(pos + 1); // Skip "."
+ }
+ for (size_t ii = 0; ii < this->fields.size(); ++ii)
+ {
+ const ShaderVariable *fieldVar = nullptr;
+ std::string originalFieldName;
+ bool found = fields[ii].findInfoByMappedName(remaining, &fieldVar, &originalFieldName);
+ if (found)
+ {
+ *originalFullName = originalName + "." + originalFieldName;
+ *leafVar = fieldVar;
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+const sh::ShaderVariable *ShaderVariable::findField(const std::string &fullName,
+ uint32_t *fieldIndexOut) const
+{
+ if (fields.empty())
+ {
+ return nullptr;
+ }
+ size_t pos = fullName.find_first_of(".");
+ std::string topName, fieldName;
+ if (pos == std::string::npos)
+ {
+ // If this is a shader I/O block without an instance name, return the field given only the
+ // field name.
+ if (!isShaderIOBlock || !name.empty())
+ {
+ return nullptr;
+ }
+
+ fieldName = fullName;
+ }
+ else
+ {
+ std::string baseName = isShaderIOBlock ? structOrBlockName : name;
+ topName = fullName.substr(0, pos);
+ if (topName != baseName)
+ {
+ return nullptr;
+ }
+ fieldName = fullName.substr(pos + 1);
+ }
+ if (fieldName.empty())
+ {
+ return nullptr;
+ }
+ for (size_t field = 0; field < fields.size(); ++field)
+ {
+ if (fields[field].name == fieldName)
+ {
+ *fieldIndexOut = static_cast<GLuint>(field);
+ return &fields[field];
+ }
+ }
+ return nullptr;
+}
+
+bool ShaderVariable::isBuiltIn() const
+{
+ return gl::IsBuiltInName(name);
+}
+
+bool ShaderVariable::isEmulatedBuiltIn() const
+{
+ return isBuiltIn() && name != mappedName;
+}
+
+bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other,
+ bool matchPrecision,
+ bool matchName) const
+{
+ if (type != other.type)
+ return false;
+ if (matchPrecision && precision != other.precision)
+ return false;
+ if (matchName && name != other.name)
+ return false;
+ ASSERT(!matchName || mappedName == other.mappedName);
+ if (arraySizes != other.arraySizes)
+ return false;
+ if (isRowMajorLayout != other.isRowMajorLayout)
+ return false;
+ if (fields.size() != other.fields.size())
+ return false;
+
+ // [OpenGL ES 3.1 SPEC Chapter 7.4.1]
+ // Variables declared as structures are considered to match in type if and only if structure
+ // members match in name, type, qualification, and declaration order.
+ for (size_t ii = 0; ii < fields.size(); ++ii)
+ {
+ if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii], matchPrecision, true))
+ {
+ return false;
+ }
+ }
+ if (structOrBlockName != other.structOrBlockName ||
+ mappedStructOrBlockName != other.mappedStructOrBlockName)
+ return false;
+ return true;
+}
+
+void ShaderVariable::updateEffectiveLocation(const sh::ShaderVariable &parent)
+{
+ if ((location < 0 || hasImplicitLocation) && !parent.hasImplicitLocation)
+ {
+ location = parent.location;
+ }
+}
+
+void ShaderVariable::resetEffectiveLocation()
+{
+ if (hasImplicitLocation)
+ {
+ location = -1;
+ }
+}
+
+bool ShaderVariable::isSameUniformAtLinkTime(const ShaderVariable &other) const
+{
+ // Enforce a consistent match.
+ // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16261
+ if (binding != -1 && other.binding != -1 && binding != other.binding)
+ {
+ return false;
+ }
+ if (imageUnitFormat != other.imageUnitFormat)
+ {
+ return false;
+ }
+ if (location != -1 && other.location != -1 && location != other.location)
+ {
+ return false;
+ }
+ if (offset != other.offset)
+ {
+ return false;
+ }
+ if (rasterOrdered != other.rasterOrdered)
+ {
+ return false;
+ }
+ if (readonly != other.readonly || writeonly != other.writeonly)
+ {
+ return false;
+ }
+ return ShaderVariable::isSameVariableAtLinkTime(other, true, true);
+}
+
+bool ShaderVariable::isSameInterfaceBlockFieldAtLinkTime(const ShaderVariable &other) const
+{
+ return (ShaderVariable::isSameVariableAtLinkTime(other, true, true));
+}
+
+bool ShaderVariable::isSameVaryingAtLinkTime(const ShaderVariable &other) const
+{
+ return isSameVaryingAtLinkTime(other, 100);
+}
+
+bool ShaderVariable::isSameVaryingAtLinkTime(const ShaderVariable &other, int shaderVersion) const
+{
+ return ShaderVariable::isSameVariableAtLinkTime(other, false, false) &&
+ InterpolationTypesMatch(interpolation, other.interpolation) &&
+ (shaderVersion >= 300 || isInvariant == other.isInvariant) &&
+ (isPatch == other.isPatch) && location == other.location &&
+ (isSameNameAtLinkTime(other) || (shaderVersion >= 310 && location >= 0));
+}
+
+bool ShaderVariable::isSameNameAtLinkTime(const ShaderVariable &other) const
+{
+ if (isShaderIOBlock != other.isShaderIOBlock)
+ {
+ return false;
+ }
+
+ if (isShaderIOBlock)
+ {
+ // Shader I/O blocks match by block name.
+ return structOrBlockName == other.structOrBlockName;
+ }
+
+ // Otherwise match by name.
+ return name == other.name;
+}
+
+InterfaceBlock::InterfaceBlock()
+ : arraySize(0),
+ layout(BLOCKLAYOUT_PACKED),
+ isRowMajorLayout(false),
+ binding(-1),
+ staticUse(false),
+ active(false),
+ blockType(BlockType::BLOCK_UNIFORM)
+{}
+
+InterfaceBlock::~InterfaceBlock() {}
+
+InterfaceBlock::InterfaceBlock(const InterfaceBlock &other)
+ : name(other.name),
+ mappedName(other.mappedName),
+ instanceName(other.instanceName),
+ arraySize(other.arraySize),
+ layout(other.layout),
+ isRowMajorLayout(other.isRowMajorLayout),
+ binding(other.binding),
+ staticUse(other.staticUse),
+ active(other.active),
+ blockType(other.blockType),
+ fields(other.fields)
+{}
+
+InterfaceBlock &InterfaceBlock::operator=(const InterfaceBlock &other)
+{
+ name = other.name;
+ mappedName = other.mappedName;
+ instanceName = other.instanceName;
+ arraySize = other.arraySize;
+ layout = other.layout;
+ isRowMajorLayout = other.isRowMajorLayout;
+ binding = other.binding;
+ staticUse = other.staticUse;
+ active = other.active;
+ blockType = other.blockType;
+ fields = other.fields;
+ return *this;
+}
+
+std::string InterfaceBlock::fieldPrefix() const
+{
+ return instanceName.empty() ? "" : name;
+}
+
+std::string InterfaceBlock::fieldMappedPrefix() const
+{
+ return instanceName.empty() ? "" : mappedName;
+}
+
+bool InterfaceBlock::isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const
+{
+ if (name != other.name || mappedName != other.mappedName || arraySize != other.arraySize ||
+ layout != other.layout || isRowMajorLayout != other.isRowMajorLayout ||
+ binding != other.binding || blockType != other.blockType ||
+ fields.size() != other.fields.size())
+ {
+ return false;
+ }
+
+ for (size_t fieldIndex = 0; fieldIndex < fields.size(); ++fieldIndex)
+ {
+ if (!fields[fieldIndex].isSameInterfaceBlockFieldAtLinkTime(other.fields[fieldIndex]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool InterfaceBlock::isBuiltIn() const
+{
+ return gl::IsBuiltInName(name);
+}
+
+void WorkGroupSize::fill(int fillValue)
+{
+ localSizeQualifiers[0] = fillValue;
+ localSizeQualifiers[1] = fillValue;
+ localSizeQualifiers[2] = fillValue;
+}
+
+void WorkGroupSize::setLocalSize(int localSizeX, int localSizeY, int localSizeZ)
+{
+ localSizeQualifiers[0] = localSizeX;
+ localSizeQualifiers[1] = localSizeY;
+ localSizeQualifiers[2] = localSizeZ;
+}
+
+// check that if one of them is less than 1, then all of them are.
+// Or if one is positive, then all of them are positive.
+bool WorkGroupSize::isLocalSizeValid() const
+{
+ return (
+ (localSizeQualifiers[0] < 1 && localSizeQualifiers[1] < 1 && localSizeQualifiers[2] < 1) ||
+ (localSizeQualifiers[0] > 0 && localSizeQualifiers[1] > 0 && localSizeQualifiers[2] > 0));
+}
+
+bool WorkGroupSize::isAnyValueSet() const
+{
+ return localSizeQualifiers[0] > 0 || localSizeQualifiers[1] > 0 || localSizeQualifiers[2] > 0;
+}
+
+bool WorkGroupSize::isDeclared() const
+{
+ bool localSizeDeclared = localSizeQualifiers[0] > 0;
+ ASSERT(isLocalSizeValid());
+ return localSizeDeclared;
+}
+
+bool WorkGroupSize::isWorkGroupSizeMatching(const WorkGroupSize &right) const
+{
+ for (size_t i = 0u; i < size(); ++i)
+ {
+ bool result = (localSizeQualifiers[i] == right.localSizeQualifiers[i] ||
+ (localSizeQualifiers[i] == 1 && right.localSizeQualifiers[i] == -1) ||
+ (localSizeQualifiers[i] == -1 && right.localSizeQualifiers[i] == 1));
+ if (!result)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+int &WorkGroupSize::operator[](size_t index)
+{
+ ASSERT(index < size());
+ return localSizeQualifiers[index];
+}
+
+int WorkGroupSize::operator[](size_t index) const
+{
+ ASSERT(index < size());
+ return localSizeQualifiers[index];
+}
+
+size_t WorkGroupSize::size() const
+{
+ return 3u;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/StaticType.h b/gfx/angle/checkout/src/compiler/translator/StaticType.h
new file mode 100644
index 0000000000..641daadebd
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/StaticType.h
@@ -0,0 +1,296 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Compile-time instances of many common TType values. These are looked up
+// (statically or dynamically) through the methods defined in the namespace.
+//
+
+#ifndef COMPILER_TRANSLATOR_STATIC_TYPE_H_
+#define COMPILER_TRANSLATOR_STATIC_TYPE_H_
+
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+namespace StaticType
+{
+
+namespace Helpers
+{
+
+//
+// Generation and static allocation of type mangled name values.
+//
+
+// Size of the constexpr-generated mangled name.
+// If this value is too small, the compiler will produce errors.
+static constexpr size_t kStaticMangledNameLength = TBasicMangledName::mangledNameSize + 1;
+
+// Type which holds the mangled names for constexpr-generated TTypes.
+// This simple struct is needed so that a char array can be returned by value.
+struct StaticMangledName
+{
+ // If this array is too small, the compiler will produce errors.
+ char name[kStaticMangledNameLength + 1] = {};
+};
+
+// Generates a mangled name for a TType given its parameters.
+constexpr StaticMangledName BuildStaticMangledName(TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize)
+{
+ StaticMangledName name = {};
+ name.name[0] = TType::GetSizeMangledName(primarySize, secondarySize);
+ TBasicMangledName typeName(basicType);
+ char *mangledName = typeName.getName();
+ static_assert(TBasicMangledName::mangledNameSize == 2, "Mangled name size is not 2");
+ name.name[1] = mangledName[0];
+ name.name[2] = mangledName[1];
+ name.name[3] = '\0';
+ return name;
+}
+
+// Similar mangled name builder but for array types. Currently, only single-dimension arrays of
+// single-digit size are necessary and supported.
+static constexpr size_t kStaticArrayMangledNameLength = kStaticMangledNameLength + 2;
+struct StaticArrayMangledName
+{
+ char name[kStaticArrayMangledNameLength + 1] = {};
+};
+constexpr StaticArrayMangledName BuildStaticArrayMangledName(TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize,
+ const unsigned int *arraySizes,
+ size_t numArraySizes)
+{
+ StaticMangledName nonArrayName =
+ BuildStaticMangledName(basicType, precision, qualifier, primarySize, secondarySize);
+
+ StaticArrayMangledName arrayName = {};
+ static_assert(kStaticMangledNameLength == 3, "Static mangled name size is not 3");
+
+ arrayName.name[0] = nonArrayName.name[0];
+ arrayName.name[1] = nonArrayName.name[1];
+ arrayName.name[2] = nonArrayName.name[2];
+ arrayName.name[3] = 'x';
+ arrayName.name[4] = static_cast<char>('0' + arraySizes[0]);
+ arrayName.name[5] = '\0';
+ return arrayName;
+}
+
+// This "variable" contains the mangled names for every constexpr-generated TType.
+// If kMangledNameInstance<B, P, Q, PS, SS> is used anywhere (specifally
+// in instance, below), this is where the appropriate type will be stored.
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize>
+static constexpr StaticMangledName kMangledNameInstance =
+ BuildStaticMangledName(basicType, precision, qualifier, primarySize, secondarySize);
+
+// Same as kMangledNameInstance, but for array types.
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize,
+ const unsigned int *arraySizes,
+ size_t numArraySizes>
+static constexpr StaticArrayMangledName kMangledNameArrayInstance =
+ BuildStaticArrayMangledName(basicType,
+ precision,
+ qualifier,
+ primarySize,
+ secondarySize,
+ arraySizes,
+ numArraySizes);
+
+//
+// Generation and static allocation of TType values.
+//
+
+// This "variable" contains every constexpr-generated TType.
+// If instance<B, P, Q, PS, SS> is used anywhere (specifally
+// in Get, below), this is where the appropriate type will be stored.
+//
+// TODO(crbug.com/981610): This is constexpr but doesn't follow the kConstant naming convention
+// because TType has a mutable member that prevents it from being in .data.rel.ro and makes the
+// Android Binary Size builder complain when ANGLE is rolled in Chromium.
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize>
+static constexpr TType instance =
+ TType(basicType,
+ precision,
+ qualifier,
+ primarySize,
+ secondarySize,
+ TSpan<const unsigned int>(),
+ kMangledNameInstance<basicType, precision, qualifier, primarySize, secondarySize>.name);
+
+// Same as instance, but for array types.
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize,
+ const unsigned int *arraySizes,
+ size_t numArraySizes>
+static constexpr TType arrayInstance =
+ TType(basicType,
+ precision,
+ qualifier,
+ primarySize,
+ secondarySize,
+ TSpan<const unsigned int>(arraySizes, numArraySizes),
+ kMangledNameArrayInstance<basicType, precision, qualifier, primarySize, secondarySize, arraySizes, numArraySizes>.name);
+
+} // namespace Helpers
+
+//
+// Fully-qualified type lookup.
+//
+
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize>
+constexpr const TType *Get()
+{
+ static_assert(1 <= primarySize && primarySize <= 4, "primarySize out of bounds");
+ static_assert(1 <= secondarySize && secondarySize <= 4, "secondarySize out of bounds");
+ return &Helpers::instance<basicType, precision, qualifier, primarySize, secondarySize>;
+}
+
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize,
+ const unsigned int *arraySizes,
+ size_t numArraySizes>
+constexpr const TType *GetArray()
+{
+ static_assert(1 <= primarySize && primarySize <= 4, "primarySize out of bounds");
+ static_assert(1 <= secondarySize && secondarySize <= 4, "secondarySize out of bounds");
+ static_assert(numArraySizes == 1, "only single-dimension static types are supported");
+ static_assert(arraySizes[0] < 10, "only single-digit dimensions are supported in static types");
+ return &Helpers::arrayInstance<basicType, precision, qualifier, primarySize, secondarySize,
+ arraySizes, numArraySizes>;
+}
+
+//
+// Overloads
+//
+
+template <TBasicType basicType,
+ TPrecision precision,
+ uint8_t primarySize = 1,
+ uint8_t secondarySize = 1>
+constexpr const TType *GetBasic()
+{
+ return Get<basicType, precision, EvqGlobal, primarySize, secondarySize>();
+}
+
+template <TBasicType basicType,
+ TPrecision precision,
+ uint8_t primarySize = 1,
+ uint8_t secondarySize = 1>
+constexpr const TType *GetTemporary()
+{
+ return Get<basicType, precision, EvqTemporary, primarySize, secondarySize>();
+}
+
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize = 1,
+ uint8_t secondarySize = 1>
+const TType *GetQualified()
+{
+ return Get<basicType, precision, qualifier, primarySize, secondarySize>();
+}
+
+// Dynamic lookup methods (convert runtime values to template args)
+
+namespace Helpers
+{
+
+// Helper which takes secondarySize statically but primarySize dynamically.
+template <TBasicType basicType, TPrecision precision, TQualifier qualifier, uint8_t secondarySize>
+constexpr const TType *GetForVecMatHelper(uint8_t primarySize)
+{
+ static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
+ basicType == EbtBool,
+ "unsupported basicType");
+ switch (primarySize)
+ {
+ case 1:
+ return Get<basicType, precision, qualifier, 1, secondarySize>();
+ case 2:
+ return Get<basicType, precision, qualifier, 2, secondarySize>();
+ case 3:
+ return Get<basicType, precision, qualifier, 3, secondarySize>();
+ case 4:
+ return Get<basicType, precision, qualifier, 4, secondarySize>();
+ default:
+ UNREACHABLE();
+ return GetBasic<EbtVoid, EbpUndefined>();
+ }
+}
+
+} // namespace Helpers
+
+template <TBasicType basicType, TPrecision precision, TQualifier qualifier = EvqGlobal>
+constexpr const TType *GetForVecMat(uint8_t primarySize, uint8_t secondarySize = 1)
+{
+ static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
+ basicType == EbtBool,
+ "unsupported basicType");
+ switch (secondarySize)
+ {
+ case 1:
+ return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 1>(primarySize);
+ case 2:
+ return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 2>(primarySize);
+ case 3:
+ return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 3>(primarySize);
+ case 4:
+ return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 4>(primarySize);
+ default:
+ UNREACHABLE();
+ return GetBasic<EbtVoid, EbpUndefined>();
+ }
+}
+
+template <TBasicType basicType, TPrecision precision>
+constexpr const TType *GetForVec(TQualifier qualifier, uint8_t size)
+{
+ switch (qualifier)
+ {
+ case EvqGlobal:
+ return Helpers::GetForVecMatHelper<basicType, precision, EvqGlobal, 1>(size);
+ case EvqParamOut:
+ return Helpers::GetForVecMatHelper<basicType, precision, EvqParamOut, 1>(size);
+ default:
+ UNREACHABLE();
+ return GetBasic<EbtVoid, EbpUndefined>();
+ }
+}
+
+} // namespace StaticType
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_STATIC_TYPE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/StructureHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/StructureHLSL.cpp
new file mode 100644
index 0000000000..eae602f5ea
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/StructureHLSL.cpp
@@ -0,0 +1,668 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// StructureHLSL.cpp:
+// HLSL translation of GLSL constructors and structures.
+//
+
+#include "compiler/translator/StructureHLSL.h"
+#include "common/utilities.h"
+#include "compiler/translator/OutputHLSL.h"
+#include "compiler/translator/Types.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+TString Define(const TStructure &structure,
+ bool useHLSLRowMajorPacking,
+ bool useStd140Packing,
+ bool forcePadding,
+ Std140PaddingHelper *padHelper)
+{
+ const TFieldList &fields = structure.fields();
+ const bool isNameless = (structure.symbolType() == SymbolType::Empty);
+ const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking,
+ useStd140Packing, forcePadding);
+ const TString declareString = (isNameless ? "struct" : "struct " + structName);
+
+ TString string;
+ string += declareString +
+ "\n"
+ "{\n";
+
+ size_t memberSize = fields.size();
+ for (const TField *field : fields)
+ {
+ memberSize--;
+ const TType &fieldType = *field->type();
+ if (!IsSampler(fieldType.getBasicType()))
+ {
+ const TStructure *fieldStruct = fieldType.getStruct();
+ const TString &fieldTypeString =
+ fieldStruct ? QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking,
+ useStd140Packing, false)
+ : TypeString(fieldType);
+
+ if (padHelper)
+ {
+ string += padHelper->prePaddingString(
+ fieldType, (memberSize != fields.size() - 1) && forcePadding);
+ }
+
+ string += " " + fieldTypeString + " " + DecorateField(field->name(), structure) +
+ ArrayString(fieldType).data() + ";\n";
+
+ if (padHelper)
+ {
+ string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking,
+ memberSize == 0, forcePadding);
+ }
+ }
+ }
+
+ // Nameless structs do not finish with a semicolon and newline, to leave room for an instance
+ // variable
+ string += (isNameless ? "} " : "};\n");
+
+ return string;
+}
+
+TString WriteParameterList(const std::vector<TType> &parameters)
+{
+ TString parameterList;
+ for (size_t parameter = 0u; parameter < parameters.size(); parameter++)
+ {
+ const TType &paramType = parameters[parameter];
+
+ parameterList +=
+ TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType).data();
+
+ if (parameter < parameters.size() - 1u)
+ {
+ parameterList += ", ";
+ }
+ }
+ return parameterList;
+}
+
+int GetElementPadding(int elementIndex, int alignment)
+{
+ const int paddingOffset = elementIndex % alignment;
+ return paddingOffset != 0 ? (alignment - paddingOffset) : 0;
+}
+
+} // anonymous namespace
+
+Std140PaddingHelper::Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
+ unsigned *uniqueCounter)
+ : mPaddingCounter(uniqueCounter), mElementIndex(0), mStructElementIndexes(&structElementIndexes)
+{}
+
+Std140PaddingHelper::Std140PaddingHelper(const Std140PaddingHelper &other)
+ : mPaddingCounter(other.mPaddingCounter),
+ mElementIndex(other.mElementIndex),
+ mStructElementIndexes(other.mStructElementIndexes)
+{}
+
+Std140PaddingHelper &Std140PaddingHelper::operator=(const Std140PaddingHelper &other)
+{
+ mPaddingCounter = other.mPaddingCounter;
+ mElementIndex = other.mElementIndex;
+ mStructElementIndexes = other.mStructElementIndexes;
+ return *this;
+}
+
+TString Std140PaddingHelper::next()
+{
+ unsigned value = (*mPaddingCounter)++;
+ return str(value);
+}
+
+int Std140PaddingHelper::prePadding(const TType &type, bool forcePadding)
+{
+ if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray())
+ {
+ if (forcePadding)
+ {
+ // Add padding between the structure's members to follow the std140 rules manually.
+ const int forcePaddingCount = GetElementPadding(mElementIndex, 4);
+ mElementIndex = 0;
+ return forcePaddingCount;
+ }
+ else
+ {
+ // no padding needed, HLSL will align the field to a new register
+ mElementIndex = 0;
+ return 0;
+ }
+ }
+
+ const GLenum glType = GLVariableType(type);
+ const int numComponents = gl::VariableComponentCount(glType);
+
+ if (numComponents >= 4)
+ {
+ if (forcePadding)
+ {
+ // Add padding between the structure's members to follow the std140 rules manually.
+ const int forcePaddingCount = GetElementPadding(mElementIndex, 4);
+ mElementIndex = numComponents % 4;
+ return forcePaddingCount;
+ }
+ else
+ {
+ // no padding needed, HLSL will align the field to a new register
+ mElementIndex = 0;
+ return 0;
+ }
+ }
+
+ if (mElementIndex + numComponents > 4)
+ {
+ if (forcePadding)
+ {
+ // Add padding between the structure's members to follow the std140 rules manually.
+ const int forcePaddingCount = GetElementPadding(mElementIndex, 4);
+ mElementIndex = numComponents;
+ return forcePaddingCount;
+ }
+ else
+ {
+ // no padding needed, HLSL will align the field to a new register
+ mElementIndex = numComponents;
+ return 0;
+ }
+ }
+
+ const int alignment = numComponents == 3 ? 4 : numComponents;
+ const int paddingCount = GetElementPadding(mElementIndex, alignment);
+
+ mElementIndex += paddingCount;
+ mElementIndex += numComponents;
+ mElementIndex %= 4;
+
+ return paddingCount;
+}
+
+TString Std140PaddingHelper::prePaddingString(const TType &type, bool forcePadding)
+{
+ int paddingCount = prePadding(type, forcePadding);
+
+ TString padding;
+
+ for (int paddingIndex = 0; paddingIndex < paddingCount; paddingIndex++)
+ {
+ padding += " float pad_" + next() + ";\n";
+ }
+
+ return padding;
+}
+
+TString Std140PaddingHelper::postPaddingString(const TType &type,
+ bool useHLSLRowMajorPacking,
+ bool isLastElement,
+ bool forcePadding)
+{
+ if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct)
+ {
+ if (forcePadding)
+ {
+ const GLenum glType = GLVariableType(type);
+ const int numComponents = gl::VariableComponentCount(glType);
+ if (isLastElement || (numComponents >= 4))
+ {
+ // If this structure will be used as HLSL StructuredBuffer member's type, in
+ // order to follow the std140 rules, add padding at the end of the structure
+ // if necessary. Or if the current element straddles a vec4 boundary, add
+ // padding to round up the base offset of the next element to the base
+ // alignment of a vec4.
+ TString forcePaddingStr;
+ const int paddingCount = GetElementPadding(mElementIndex, 4);
+ for (int paddingIndex = 0; paddingIndex < paddingCount; paddingIndex++)
+ {
+ forcePaddingStr += " float pad_" + next() + ";\n";
+ }
+ mElementIndex = 0;
+ return forcePaddingStr;
+ }
+ }
+
+ return "";
+ }
+
+ int numComponents = 0;
+ const TStructure *structure = type.getStruct();
+
+ if (type.isMatrix())
+ {
+ // This method can also be called from structureString, which does not use layout
+ // qualifiers.
+ // Thus, use the method parameter for determining the matrix packing.
+ //
+ // Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we
+ // wish to always transpose GL matrices to play well with HLSL's matrix array indexing.
+ //
+ const bool isRowMajorMatrix = !useHLSLRowMajorPacking;
+ const GLenum glType = GLVariableType(type);
+ numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix);
+ }
+ else if (structure)
+ {
+ const TString &structName =
+ QualifiedStructNameString(*structure, useHLSLRowMajorPacking, true, false);
+ numComponents = mStructElementIndexes->find(structName)->second;
+
+ if (numComponents == 0)
+ {
+ return "";
+ }
+ }
+ else
+ {
+ const GLenum glType = GLVariableType(type);
+ numComponents = gl::VariableComponentCount(glType);
+ }
+
+ TString padding;
+ for (int paddingOffset = numComponents; paddingOffset < 4; paddingOffset++)
+ {
+ padding += " float pad_" + next() + ";\n";
+ }
+ return padding;
+}
+
+StructureHLSL::StructureHLSL() : mUniquePaddingCounter(0) {}
+
+Std140PaddingHelper StructureHLSL::getPaddingHelper()
+{
+ return Std140PaddingHelper(mStd140StructElementIndexes, &mUniquePaddingCounter);
+}
+
+TString StructureHLSL::defineQualified(const TStructure &structure,
+ bool useHLSLRowMajorPacking,
+ bool useStd140Packing,
+ bool forcePadding)
+{
+ if (useStd140Packing)
+ {
+ Std140PaddingHelper padHelper = getPaddingHelper();
+ return Define(structure, useHLSLRowMajorPacking, useStd140Packing, forcePadding,
+ &padHelper);
+ }
+ else
+ {
+ return Define(structure, useHLSLRowMajorPacking, useStd140Packing, false, nullptr);
+ }
+}
+
+TString StructureHLSL::defineNameless(const TStructure &structure)
+{
+ return Define(structure, false, false, false, nullptr);
+}
+
+StructureHLSL::DefinedStructs::iterator StructureHLSL::defineVariants(const TStructure &structure,
+ const TString &name)
+{
+ ASSERT(mDefinedStructs.find(name) == mDefinedStructs.end());
+
+ for (const TField *field : structure.fields())
+ {
+ const TType *fieldType = field->type();
+ if (fieldType->getBasicType() == EbtStruct)
+ {
+ ensureStructDefined(*fieldType->getStruct());
+ }
+ }
+
+ DefinedStructs::iterator addedStruct =
+ mDefinedStructs.insert(std::make_pair(name, new TStructProperties())).first;
+ // Add element index
+ storeStd140ElementIndex(structure, false);
+ storeStd140ElementIndex(structure, true);
+
+ const TString &structString = defineQualified(structure, false, false, false);
+
+ ASSERT(std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) ==
+ mStructDeclarations.end());
+ // Add row-major packed struct for interface blocks
+ TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
+ defineQualified(structure, true, false, false) +
+ "#pragma pack_matrix(column_major)\n";
+
+ TString std140String = defineQualified(structure, false, true, false);
+ TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
+ defineQualified(structure, true, true, false) +
+ "#pragma pack_matrix(column_major)\n";
+
+ // Must force to pad the structure's elements for StructuredBuffer's element type, if qualifier
+ // of structure is std140.
+ TString std140ForcePaddingString = defineQualified(structure, false, true, true);
+ TString std140RowMajorForcePaddingString = "#pragma pack_matrix(row_major)\n" +
+ defineQualified(structure, true, true, true) +
+ "#pragma pack_matrix(column_major)\n";
+
+ mStructDeclarations.push_back(structString);
+ mStructDeclarations.push_back(rowMajorString);
+ mStructDeclarations.push_back(std140String);
+ mStructDeclarations.push_back(std140RowMajorString);
+ mStructDeclarations.push_back(std140ForcePaddingString);
+ mStructDeclarations.push_back(std140RowMajorForcePaddingString);
+ return addedStruct;
+}
+
+void StructureHLSL::ensureStructDefined(const TStructure &structure)
+{
+ const TString name = StructNameString(structure);
+ if (name == "")
+ {
+ return; // Nameless structures are not defined
+ }
+ if (mDefinedStructs.find(name) == mDefinedStructs.end())
+ {
+ defineVariants(structure, name);
+ }
+}
+
+TString StructureHLSL::addStructConstructor(const TStructure &structure)
+{
+ const TString name = StructNameString(structure);
+
+ if (name == "")
+ {
+ return TString(); // Nameless structures don't have constructors
+ }
+
+ auto definedStruct = mDefinedStructs.find(name);
+ if (definedStruct == mDefinedStructs.end())
+ {
+ definedStruct = defineVariants(structure, name);
+ }
+ const TString constructorFunctionName = TString(name) + "_ctor";
+ TString *constructor = &definedStruct->second->constructor;
+ if (!constructor->empty())
+ {
+ return constructorFunctionName; // Already added
+ }
+ *constructor += name + " " + constructorFunctionName + "(";
+
+ std::vector<TType> ctorParameters;
+ const TFieldList &fields = structure.fields();
+ for (const TField *field : fields)
+ {
+ const TType *fieldType = field->type();
+ if (!IsSampler(fieldType->getBasicType()))
+ {
+ ctorParameters.push_back(*fieldType);
+ }
+ }
+ // Structs that have sampler members should not have constructor calls, and otherwise structs
+ // are guaranteed to be non-empty by the grammar. Structs can't contain empty declarations
+ // either.
+ ASSERT(!ctorParameters.empty());
+
+ *constructor += WriteParameterList(ctorParameters);
+
+ *constructor +=
+ ")\n"
+ "{\n"
+ " " +
+ name + " structure = { ";
+
+ for (size_t parameterIndex = 0u; parameterIndex < ctorParameters.size(); ++parameterIndex)
+ {
+ *constructor += "x" + str(parameterIndex);
+ if (parameterIndex < ctorParameters.size() - 1u)
+ {
+ *constructor += ", ";
+ }
+ }
+ *constructor +=
+ "};\n"
+ " return structure;\n"
+ "}\n";
+
+ return constructorFunctionName;
+}
+
+TString StructureHLSL::addBuiltInConstructor(const TType &type, const TIntermSequence *parameters)
+{
+ ASSERT(!type.isArray());
+ ASSERT(type.getStruct() == nullptr);
+ ASSERT(parameters);
+
+ TType ctorType = type;
+ ctorType.setPrecision(EbpHigh);
+ ctorType.setQualifier(EvqTemporary);
+
+ const TString constructorFunctionName =
+ TString(type.getBuiltInTypeNameString()) + "_ctor" + DisambiguateFunctionName(parameters);
+ TString constructor = TypeString(ctorType) + " " + constructorFunctionName + "(";
+
+ std::vector<TType> ctorParameters;
+ for (auto parameter : *parameters)
+ {
+ const TType &paramType = parameter->getAsTyped()->getType();
+ ASSERT(!paramType.isArray());
+ ctorParameters.push_back(paramType);
+ }
+ constructor += WriteParameterList(ctorParameters);
+
+ constructor +=
+ ")\n"
+ "{\n"
+ " return " +
+ TypeString(ctorType) + "(";
+
+ if (ctorType.isMatrix() && ctorParameters.size() == 1)
+ {
+ uint8_t rows = ctorType.getRows();
+ uint8_t cols = ctorType.getCols();
+ const TType &parameter = ctorParameters[0];
+
+ if (parameter.isScalar())
+ {
+ for (uint8_t col = 0; col < cols; col++)
+ {
+ for (uint8_t row = 0; row < rows; row++)
+ {
+ constructor += TString((row == col) ? "x0" : "0.0");
+
+ if (row < rows - 1 || col < cols - 1)
+ {
+ constructor += ", ";
+ }
+ }
+ }
+ }
+ else if (parameter.isMatrix())
+ {
+ for (uint8_t col = 0; col < cols; col++)
+ {
+ for (uint8_t row = 0; row < rows; row++)
+ {
+ if (row < parameter.getRows() && col < parameter.getCols())
+ {
+ constructor += TString("x0") + "[" + str(col) + "][" + str(row) + "]";
+ }
+ else
+ {
+ constructor += TString((row == col) ? "1.0" : "0.0");
+ }
+
+ if (row < rows - 1 || col < cols - 1)
+ {
+ constructor += ", ";
+ }
+ }
+ }
+ }
+ else
+ {
+ ASSERT(rows == 2 && cols == 2 && parameter.isVector() &&
+ parameter.getNominalSize() == 4);
+
+ constructor += "x0";
+ }
+ }
+ else
+ {
+ size_t remainingComponents = ctorType.getObjectSize();
+ size_t parameterIndex = 0;
+
+ while (remainingComponents > 0)
+ {
+ const TType &parameter = ctorParameters[parameterIndex];
+ const size_t parameterSize = parameter.getObjectSize();
+ bool moreParameters = parameterIndex + 1 < ctorParameters.size();
+
+ constructor += "x" + str(parameterIndex);
+
+ if (parameter.isScalar())
+ {
+ remainingComponents -= parameter.getObjectSize();
+ }
+ else if (parameter.isVector())
+ {
+ if (remainingComponents == parameterSize || moreParameters)
+ {
+ ASSERT(parameterSize <= remainingComponents);
+ remainingComponents -= parameterSize;
+ }
+ else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize()))
+ {
+ switch (remainingComponents)
+ {
+ case 1:
+ constructor += ".x";
+ break;
+ case 2:
+ constructor += ".xy";
+ break;
+ case 3:
+ constructor += ".xyz";
+ break;
+ case 4:
+ constructor += ".xyzw";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ remainingComponents = 0;
+ }
+ else
+ UNREACHABLE();
+ }
+ else if (parameter.isMatrix())
+ {
+ uint8_t column = 0;
+ while (remainingComponents > 0 && column < parameter.getCols())
+ {
+ constructor += "[" + str(column) + "]";
+
+ if (remainingComponents < static_cast<size_t>(parameter.getRows()))
+ {
+ switch (remainingComponents)
+ {
+ case 1:
+ constructor += ".x";
+ break;
+ case 2:
+ constructor += ".xy";
+ break;
+ case 3:
+ constructor += ".xyz";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ remainingComponents = 0;
+ }
+ else
+ {
+ remainingComponents -= parameter.getRows();
+
+ if (remainingComponents > 0)
+ {
+ constructor += ", x" + str(parameterIndex);
+ }
+ }
+
+ column++;
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ if (moreParameters)
+ {
+ parameterIndex++;
+ }
+
+ if (remainingComponents)
+ {
+ constructor += ", ";
+ }
+ }
+ }
+
+ constructor +=
+ ");\n"
+ "}\n";
+
+ mBuiltInConstructors.insert(constructor);
+
+ return constructorFunctionName;
+}
+
+std::string StructureHLSL::structsHeader() const
+{
+ TInfoSinkBase out;
+
+ for (auto &declaration : mStructDeclarations)
+ {
+ out << declaration;
+ }
+
+ for (auto &structure : mDefinedStructs)
+ {
+ out << structure.second->constructor;
+ }
+
+ for (auto &constructor : mBuiltInConstructors)
+ {
+ out << constructor;
+ }
+
+ return out.str();
+}
+
+void StructureHLSL::storeStd140ElementIndex(const TStructure &structure,
+ bool useHLSLRowMajorPacking)
+{
+ Std140PaddingHelper padHelper = getPaddingHelper();
+ const TFieldList &fields = structure.fields();
+
+ for (const TField *field : fields)
+ {
+ padHelper.prePadding(*field->type(), false);
+ }
+
+ // Add remaining element index to the global map, for use with nested structs in standard
+ // layouts
+ const TString &structName =
+ QualifiedStructNameString(structure, useHLSLRowMajorPacking, true, false);
+ mStd140StructElementIndexes[structName] = padHelper.elementIndex();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/StructureHLSL.h b/gfx/angle/checkout/src/compiler/translator/StructureHLSL.h
new file mode 100644
index 0000000000..7f3b0356f7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/StructureHLSL.h
@@ -0,0 +1,102 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// StructureHLSL.h:
+// HLSL translation of GLSL constructors and structures.
+//
+
+#ifndef COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
+#define COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/IntermNode.h"
+
+#include <set>
+
+class TInfoSinkBase;
+class TScopeBracket;
+
+namespace sh
+{
+
+// This helper class assists structure and interface block definitions in determining
+// how to pack std140 structs within HLSL's packing rules.
+class Std140PaddingHelper
+{
+ public:
+ explicit Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
+ unsigned int *uniqueCounter);
+ Std140PaddingHelper(const Std140PaddingHelper &other);
+ Std140PaddingHelper &operator=(const Std140PaddingHelper &other);
+
+ int elementIndex() const { return mElementIndex; }
+ int prePadding(const TType &type, bool forcePadding);
+ TString prePaddingString(const TType &type, bool forcePadding);
+ TString postPaddingString(const TType &type,
+ bool useHLSLRowMajorPacking,
+ bool isLastElement,
+ bool forcePadding);
+
+ private:
+ TString next();
+
+ unsigned *mPaddingCounter;
+ int mElementIndex;
+ const std::map<TString, int> *mStructElementIndexes;
+};
+
+class StructureHLSL : angle::NonCopyable
+{
+ public:
+ StructureHLSL();
+
+ // Returns the name of the constructor function.
+ TString addStructConstructor(const TStructure &structure);
+ TString addBuiltInConstructor(const TType &type, const TIntermSequence *parameters);
+
+ static TString defineNameless(const TStructure &structure);
+ void ensureStructDefined(const TStructure &structure);
+
+ std::string structsHeader() const;
+
+ Std140PaddingHelper getPaddingHelper();
+
+ private:
+ unsigned mUniquePaddingCounter;
+
+ std::map<TString, int> mStd140StructElementIndexes;
+
+ struct TStructProperties : public angle::NonCopyable
+ {
+ POOL_ALLOCATOR_NEW_DELETE
+
+ TStructProperties() {}
+
+ // Constructor is an empty string in case the struct doesn't have a constructor yet.
+ TString constructor;
+ };
+
+ // Map from struct name to struct properties.
+ typedef std::map<TString, TStructProperties *> DefinedStructs;
+ DefinedStructs mDefinedStructs;
+
+ // Struct declarations need to be kept in a vector instead of having them inside mDefinedStructs
+ // since maintaining the original order is necessary for nested structs.
+ typedef std::vector<TString> StructDeclarations;
+ StructDeclarations mStructDeclarations;
+
+ typedef std::set<TString> BuiltInConstructors;
+ BuiltInConstructors mBuiltInConstructors;
+
+ void storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking);
+ TString defineQualified(const TStructure &structure,
+ bool useHLSLRowMajorPacking,
+ bool useStd140Packing,
+ bool forcePackingEnd);
+ DefinedStructs::iterator defineVariants(const TStructure &structure, const TString &name);
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Symbol.cpp b/gfx/angle/checkout/src/compiler/translator/Symbol.cpp
new file mode 100644
index 0000000000..dddf770715
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Symbol.cpp
@@ -0,0 +1,254 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Symbol.cpp: Symbols representing variables, functions, structures and interface blocks.
+//
+
+#if defined(_MSC_VER)
+# pragma warning(disable : 4718)
+#endif
+
+#include "compiler/translator/Symbol.h"
+
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kMainName("main");
+constexpr const ImmutableString kImageLoadName("imageLoad");
+constexpr const ImmutableString kImageStoreName("imageStore");
+constexpr const ImmutableString kImageSizeName("imageSize");
+constexpr const ImmutableString kImageAtomicExchangeName("imageAtomicExchange");
+constexpr const ImmutableString kAtomicCounterName("atomicCounter");
+
+static const char kFunctionMangledNameSeparator = '(';
+
+} // anonymous namespace
+
+TSymbol::TSymbol(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ SymbolClass symbolClass,
+ TExtension extension)
+ : mName(name),
+ mUniqueId(symbolTable->nextUniqueId()),
+ mExtensions(
+ std::array<TExtension, 3u>{{extension, TExtension::UNDEFINED, TExtension::UNDEFINED}}),
+ mSymbolType(symbolType),
+ mSymbolClass(symbolClass)
+{
+ ASSERT(mSymbolType == SymbolType::BuiltIn || extension == TExtension::UNDEFINED);
+ ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
+ mSymbolType == SymbolType::Empty);
+}
+
+TSymbol::TSymbol(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ SymbolClass symbolClass,
+ const std::array<TExtension, 3u> &extensions)
+ : mName(name),
+ mUniqueId(symbolTable->nextUniqueId()),
+ mExtensions(extensions),
+ mSymbolType(symbolType),
+ mSymbolClass(symbolClass)
+{
+ ASSERT(mSymbolType == SymbolType::BuiltIn || extensions[0] == TExtension::UNDEFINED);
+ ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
+ mSymbolType == SymbolType::Empty);
+}
+
+ImmutableString TSymbol::name() const
+{
+ if (!mName.empty())
+ {
+ return mName;
+ }
+ // This can be called for nameless function parameters in HLSL.
+ ASSERT(mSymbolType == SymbolType::AngleInternal ||
+ (mSymbolType == SymbolType::Empty && isVariable()));
+ int uniqueId = mUniqueId.get();
+ ImmutableStringBuilder symbolNameOut(sizeof(uniqueId) * 2u + 1u);
+ symbolNameOut << 's';
+ symbolNameOut.appendHex(mUniqueId.get());
+ return symbolNameOut;
+}
+
+ImmutableString TSymbol::getMangledName() const
+{
+ if (mSymbolClass == SymbolClass::Function)
+ {
+ // We do this instead of using proper virtual functions so that we can better support
+ // constexpr symbols.
+ return static_cast<const TFunction *>(this)->getFunctionMangledName();
+ }
+ ASSERT(mSymbolType != SymbolType::Empty);
+ return name();
+}
+
+TVariable::TVariable(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TType *type,
+ SymbolType symbolType,
+ TExtension extension)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::Variable, extension),
+ mType(type),
+ unionArray(nullptr)
+{
+ ASSERT(mType);
+ ASSERT(name.empty() || symbolType != SymbolType::Empty);
+}
+
+TVariable::TVariable(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TType *type,
+ SymbolType symbolType,
+ const std::array<TExtension, 3u> &extensions)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::Variable, extensions),
+ mType(type),
+ unionArray(nullptr)
+{
+ ASSERT(mType);
+ ASSERT(name.empty() || symbolType != SymbolType::Empty);
+}
+
+TStructure::TStructure(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ SymbolType symbolType)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::Struct), TFieldListCollection(fields)
+{}
+
+void TStructure::createSamplerSymbols(const char *namePrefix,
+ const TString &apiNamePrefix,
+ TVector<const TVariable *> *outputSymbols,
+ TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+ TSymbolTable *symbolTable) const
+{
+ ASSERT(containsSamplers());
+ for (const auto *field : *mFields)
+ {
+ const TType *fieldType = field->type();
+ if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
+ {
+ std::stringstream fieldName = sh::InitializeStream<std::stringstream>();
+ fieldName << namePrefix << "_" << field->name();
+ TString fieldApiName = apiNamePrefix + ".";
+ fieldApiName += field->name().data();
+ fieldType->createSamplerSymbols(ImmutableString(fieldName.str()), fieldApiName,
+ outputSymbols, outputSymbolsToAPINames, symbolTable);
+ }
+ }
+}
+
+void TStructure::setName(const ImmutableString &name)
+{
+ ImmutableString *mutableName = const_cast<ImmutableString *>(&mName);
+ *mutableName = name;
+}
+
+TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ const TLayoutQualifier &layoutQualifier,
+ SymbolType symbolType,
+ TExtension extension)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::InterfaceBlock, extension),
+ TFieldListCollection(fields),
+ mBlockStorage(layoutQualifier.blockStorage),
+ mBinding(layoutQualifier.binding)
+{
+ ASSERT(name != nullptr);
+}
+
+TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ const TLayoutQualifier &layoutQualifier,
+ SymbolType symbolType,
+ const std::array<TExtension, 3u> &extensions)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::InterfaceBlock, extensions),
+ TFieldListCollection(fields),
+ mBlockStorage(layoutQualifier.blockStorage),
+ mBinding(layoutQualifier.binding)
+{
+ ASSERT(name != nullptr);
+}
+
+TFunction::TFunction(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ const TType *retType,
+ bool knownToNotHaveSideEffects)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::Function, TExtension::UNDEFINED),
+ mParametersVector(new TParamVector()),
+ mParameters(nullptr),
+ returnType(retType),
+ mMangledName(""),
+ mParamCount(0u),
+ mOp(EOpNull),
+ defined(false),
+ mHasPrototypeDeclaration(false),
+ mKnownToNotHaveSideEffects(knownToNotHaveSideEffects),
+ mHasVoidParameter(false)
+{
+ // Functions with an empty name are not allowed.
+ ASSERT(symbolType != SymbolType::Empty);
+ ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal);
+}
+
+void TFunction::addParameter(const TVariable *p)
+{
+ ASSERT(mParametersVector);
+ mParametersVector->push_back(p);
+ mParameters = mParametersVector->data();
+ mParamCount = mParametersVector->size();
+ mMangledName = kEmptyImmutableString;
+}
+
+void TFunction::shareParameters(const TFunction &parametersSource)
+{
+ mParametersVector = nullptr;
+ mParameters = parametersSource.mParameters;
+ mParamCount = parametersSource.mParamCount;
+ ASSERT(parametersSource.name() == name());
+ mMangledName = parametersSource.mMangledName;
+}
+
+ImmutableString TFunction::buildMangledName() const
+{
+ ImmutableString name = this->name();
+ std::string newName(name.data(), name.length());
+ newName += kFunctionMangledNameSeparator;
+
+ for (size_t i = 0u; i < mParamCount; ++i)
+ {
+ newName += mParameters[i]->getType().getMangledName();
+ }
+ return ImmutableString(newName);
+}
+
+bool TFunction::isMain() const
+{
+ return symbolType() == SymbolType::UserDefined && name() == kMainName;
+}
+
+bool TFunction::isImageFunction() const
+{
+ return symbolType() == SymbolType::BuiltIn &&
+ (name() == kImageSizeName || name() == kImageLoadName || name() == kImageStoreName ||
+ name() == kImageAtomicExchangeName);
+}
+
+bool TFunction::isAtomicCounterFunction() const
+{
+ return SymbolType() == SymbolType::BuiltIn && name().beginsWith(kAtomicCounterName);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Symbol.h b/gfx/angle/checkout/src/compiler/translator/Symbol.h
new file mode 100644
index 0000000000..cb34306be8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Symbol.h
@@ -0,0 +1,402 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Symbol.h: Symbols representing variables, functions, structures and interface blocks.
+//
+
+#ifndef COMPILER_TRANSLATOR_SYMBOL_H_
+#define COMPILER_TRANSLATOR_SYMBOL_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolUniqueId.h"
+
+namespace sh
+{
+
+class TSymbolTable;
+
+// Symbol base class. (Can build functions or variables out of these...)
+class TSymbol : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TSymbol(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ SymbolClass symbolClass,
+ TExtension extension = TExtension::UNDEFINED);
+
+ TSymbol(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ SymbolClass symbolClass,
+ const std::array<TExtension, 3u> &extensions);
+
+ // Note that we can't have a virtual destructor in order to support constexpr symbols. Data is
+ // either statically allocated or pool allocated.
+ ~TSymbol() = default;
+
+ // Calling name() for empty symbols (symbolType == SymbolType::Empty) generates a similar name
+ // as for internal variables.
+ ImmutableString name() const;
+ // Don't call getMangledName() for empty symbols (symbolType == SymbolType::Empty).
+ ImmutableString getMangledName() const;
+
+ bool isFunction() const { return mSymbolClass == SymbolClass::Function; }
+ bool isVariable() const { return mSymbolClass == SymbolClass::Variable; }
+ bool isStruct() const { return mSymbolClass == SymbolClass::Struct; }
+ bool isInterfaceBlock() const { return mSymbolClass == SymbolClass::InterfaceBlock; }
+
+ const TSymbolUniqueId &uniqueId() const { return mUniqueId; }
+ SymbolType symbolType() const { return mSymbolType; }
+ const std::array<TExtension, 3u> extensions() const { return mExtensions; }
+
+ template <size_t ExtensionCount>
+ constexpr const std::array<TExtension, 3u> CreateExtensionList(
+ const std::array<TExtension, ExtensionCount> &extensions)
+ {
+ switch (extensions.size())
+ {
+ case 1:
+ return std::array<TExtension, 3u>{
+ {extensions[0], TExtension::UNDEFINED, TExtension::UNDEFINED}};
+ case 2:
+ return std::array<TExtension, 3u>{
+ {extensions[0], extensions[1], TExtension::UNDEFINED}};
+ case 3:
+ return std::array<TExtension, 3u>{{extensions[0], extensions[1], extensions[2]}};
+ default:
+ UNREACHABLE();
+ return std::array<TExtension, 3u>{
+ {TExtension::UNDEFINED, TExtension::UNDEFINED, TExtension::UNDEFINED}};
+ }
+ }
+
+ protected:
+ template <size_t ExtensionCount>
+ constexpr TSymbol(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ const std::array<TExtension, ExtensionCount> &extensions,
+ SymbolClass symbolClass)
+ : mName(name),
+ mUniqueId(id),
+ mExtensions(CreateExtensionList(extensions)),
+ mSymbolType(symbolType),
+ mSymbolClass(symbolClass)
+ {}
+
+ const ImmutableString mName;
+
+ private:
+ const TSymbolUniqueId mUniqueId;
+ const std::array<TExtension, 3u> mExtensions;
+ const SymbolType mSymbolType : 4;
+
+ // We use this instead of having virtual functions for querying the class in order to support
+ // constexpr symbols.
+ const SymbolClass mSymbolClass : 4;
+};
+
+static_assert(sizeof(TSymbol) <= 24, "Size check failed");
+
+// Variable.
+// May store the value of a constant variable of any type (float, int, bool or struct).
+class TVariable : public TSymbol
+{
+ public:
+ TVariable(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TType *type,
+ SymbolType symbolType,
+ TExtension ext = TExtension::UNDEFINED);
+
+ TVariable(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TType *type,
+ SymbolType symbolType,
+ const std::array<TExtension, 3u> &extensions);
+
+ const TType &getType() const { return *mType; }
+
+ const TConstantUnion *getConstPointer() const { return unionArray; }
+
+ void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
+
+ // Note: only to be used for built-in variables with autogenerated ids!
+ constexpr TVariable(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ TExtension extension,
+ const TType *type)
+ : TSymbol(id,
+ name,
+ symbolType,
+ std::array<TExtension, 1u>{{extension}},
+ SymbolClass::Variable),
+ mType(type),
+ unionArray(nullptr)
+ {}
+
+ template <size_t ExtensionCount>
+ constexpr TVariable(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ const std::array<TExtension, ExtensionCount> &extensions,
+ const TType *type)
+ : TSymbol(id, name, symbolType, extensions, SymbolClass::Variable),
+ mType(type),
+ unionArray(nullptr)
+ {}
+
+ private:
+ const TType *mType;
+ const TConstantUnion *unionArray;
+};
+
+// Struct type.
+class TStructure : public TSymbol, public TFieldListCollection
+{
+ public:
+ TStructure(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ SymbolType symbolType);
+
+ // The char arrays passed in must be pool allocated or static.
+ void createSamplerSymbols(const char *namePrefix,
+ const TString &apiNamePrefix,
+ TVector<const TVariable *> *outputSymbols,
+ TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+ TSymbolTable *symbolTable) const;
+
+ void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; }
+ bool atGlobalScope() const { return mAtGlobalScope; }
+
+ private:
+ friend class TSymbolTable;
+ // For creating built-in structs.
+ TStructure(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ TExtension extension,
+ const TFieldList *fields)
+ : TSymbol(id,
+ name,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{extension}},
+ SymbolClass::Struct),
+ TFieldListCollection(fields)
+ {}
+
+ template <size_t ExtensionCount>
+ TStructure(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ const std::array<TExtension, ExtensionCount> &extensions,
+ const TFieldList *fields)
+ : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Struct),
+ TFieldListCollection(fields)
+ {}
+
+ // TODO(zmo): Find a way to get rid of the const_cast in function
+ // setName(). At the moment keep this function private so only
+ // friend class RegenerateStructNames may call it.
+ friend class RegenerateStructNamesTraverser;
+ void setName(const ImmutableString &name);
+
+ bool mAtGlobalScope;
+};
+
+// Interface block. Note that this contains the block name, not the instance name. Interface block
+// instances are stored as TVariable.
+class TInterfaceBlock : public TSymbol, public TFieldListCollection
+{
+ public:
+ TInterfaceBlock(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ const TLayoutQualifier &layoutQualifier,
+ SymbolType symbolType,
+ TExtension extension = TExtension::UNDEFINED);
+
+ TInterfaceBlock(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ const TLayoutQualifier &layoutQualifier,
+ SymbolType symbolType,
+ const std::array<TExtension, 3u> &extensions);
+
+ TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
+ int blockBinding() const { return mBinding; }
+
+ private:
+ friend class TSymbolTable;
+ // For creating built-in interface blocks.
+ TInterfaceBlock(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ TExtension extension,
+ const TFieldList *fields)
+ : TSymbol(id,
+ name,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{extension}},
+ SymbolClass::InterfaceBlock),
+ TFieldListCollection(fields),
+ mBlockStorage(EbsUnspecified),
+ mBinding(0)
+ {}
+
+ template <size_t ExtensionCount>
+ TInterfaceBlock(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ const std::array<TExtension, ExtensionCount> &extensions,
+ const TFieldList *fields)
+ : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::InterfaceBlock),
+ TFieldListCollection(fields),
+ mBlockStorage(EbsUnspecified),
+ mBinding(0)
+ {}
+
+ TLayoutBlockStorage mBlockStorage;
+ int mBinding;
+
+ // Note that we only record matrix packing on a per-field granularity.
+};
+
+// Parameter class used for parsing user-defined function parameters.
+struct TParameter
+{
+ // Destructively converts to TVariable.
+ // This method resets name and type to nullptrs to make sure
+ // their content cannot be modified after the call.
+ const TVariable *createVariable(TSymbolTable *symbolTable)
+ {
+ const ImmutableString constName(name);
+ const TType *constType = type;
+ name = nullptr;
+ type = nullptr;
+ return new TVariable(symbolTable, constName, constType,
+ constName.empty() ? SymbolType::Empty : SymbolType::UserDefined);
+ }
+
+ const char *name; // either pool allocated or static.
+ TType *type;
+};
+
+// The function sub-class of a symbol.
+class TFunction : public TSymbol
+{
+ public:
+ // User-defined function
+ TFunction(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ const TType *retType,
+ bool knownToNotHaveSideEffects);
+
+ void addParameter(const TVariable *p);
+ void shareParameters(const TFunction &parametersSource);
+
+ ImmutableString getFunctionMangledName() const
+ {
+ ASSERT(symbolType() != SymbolType::BuiltIn);
+ if (mMangledName.empty())
+ {
+ mMangledName = buildMangledName();
+ }
+ return mMangledName;
+ }
+
+ const TType &getReturnType() const { return *returnType; }
+
+ TOperator getBuiltInOp() const { return mOp; }
+
+ void setDefined() { defined = true; }
+ bool isDefined() const { return defined; }
+ void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
+ bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }
+ void setHasVoidParameter() { mHasVoidParameter = true; }
+ bool hasVoidParameter() const { return mHasVoidParameter; }
+
+ size_t getParamCount() const { return mParamCount; }
+ const TVariable *getParam(size_t i) const { return mParameters[i]; }
+
+ bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; }
+
+ bool isMain() const;
+ bool isImageFunction() const;
+ bool isAtomicCounterFunction() const;
+
+ // Note: Only to be used for static built-in functions!
+ constexpr TFunction(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ TExtension extension,
+ const TVariable *const *parameters,
+ size_t paramCount,
+ const TType *retType,
+ TOperator op,
+ bool knownToNotHaveSideEffects)
+ : TSymbol(id,
+ name,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{extension}},
+ SymbolClass::Function),
+ mParametersVector(nullptr),
+ mParameters(parameters),
+ returnType(retType),
+ mMangledName(nullptr),
+ mParamCount(paramCount),
+ mOp(op),
+ defined(false),
+ mHasPrototypeDeclaration(false),
+ mKnownToNotHaveSideEffects(knownToNotHaveSideEffects),
+ mHasVoidParameter(false)
+ {}
+
+ template <size_t ExtensionCount>
+ constexpr TFunction(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ const std::array<TExtension, ExtensionCount> &extensions,
+ const TVariable *const *parameters,
+ size_t paramCount,
+ const TType *retType,
+ TOperator op,
+ bool knownToNotHaveSideEffects)
+ : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Function),
+ mParametersVector(nullptr),
+ mParameters(parameters),
+ returnType(retType),
+ mMangledName(nullptr),
+ mParamCount(paramCount),
+ mOp(op),
+ defined(false),
+ mHasPrototypeDeclaration(false),
+ mKnownToNotHaveSideEffects(knownToNotHaveSideEffects),
+ mHasVoidParameter(false)
+ {}
+
+ private:
+ ImmutableString buildMangledName() const;
+
+ typedef TVector<const TVariable *> TParamVector;
+ TParamVector *mParametersVector;
+ const TVariable *const *mParameters;
+ const TType *const returnType;
+ mutable ImmutableString mMangledName;
+ size_t mParamCount : 32;
+ const TOperator mOp; // Only set for built-ins
+ bool defined : 1;
+ bool mHasPrototypeDeclaration : 1;
+ bool mKnownToNotHaveSideEffects : 1;
+ // Whether the parameter list of the function starts with void. This is used to generate an
+ // error if any other parameter follows.
+ bool mHasVoidParameter : 1;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SYMBOL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp b/gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp
new file mode 100644
index 0000000000..8424f474f7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp
@@ -0,0 +1,559 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Symbol table for parsing. The design principles and most of the functionality are documented in
+// the header file.
+//
+
+#if defined(_MSC_VER)
+# pragma warning(disable : 4718)
+#endif
+
+#include "compiler/translator/SymbolTable.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+namespace
+{
+bool CheckShaderType(Shader expected, GLenum actual)
+{
+ switch (expected)
+ {
+ case Shader::ALL:
+ return true;
+ case Shader::FRAGMENT:
+ return actual == GL_FRAGMENT_SHADER;
+ case Shader::VERTEX:
+ return actual == GL_VERTEX_SHADER;
+ case Shader::COMPUTE:
+ return actual == GL_COMPUTE_SHADER;
+ case Shader::GEOMETRY:
+ return actual == GL_GEOMETRY_SHADER;
+ case Shader::GEOMETRY_EXT:
+ return actual == GL_GEOMETRY_SHADER_EXT;
+ case Shader::TESS_CONTROL_EXT:
+ return actual == GL_TESS_CONTROL_SHADER_EXT;
+ case Shader::TESS_EVALUATION_EXT:
+ return actual == GL_TESS_EVALUATION_SHADER_EXT;
+ case Shader::NOT_COMPUTE:
+ return actual != GL_COMPUTE_SHADER;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool CheckExtension(uint32_t extensionIndex, const ShBuiltInResources &resources)
+{
+ const int *resourcePtr = reinterpret_cast<const int *>(&resources);
+ return resourcePtr[extensionIndex] > 0;
+}
+} // namespace
+
+class TSymbolTable::TSymbolTableLevel
+{
+ public:
+ TSymbolTableLevel() = default;
+
+ bool insert(TSymbol *symbol);
+
+ // Insert a function using its unmangled name as the key.
+ void insertUnmangled(TFunction *function);
+
+ TSymbol *find(const ImmutableString &name) const;
+
+ private:
+ using tLevel = TUnorderedMap<ImmutableString,
+ TSymbol *,
+ ImmutableString::FowlerNollVoHash<sizeof(size_t)>>;
+ using tLevelPair = const tLevel::value_type;
+ using tInsertResult = std::pair<tLevel::iterator, bool>;
+
+ tLevel level;
+};
+
+bool TSymbolTable::TSymbolTableLevel::insert(TSymbol *symbol)
+{
+ // returning true means symbol was added to the table
+ tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
+ return result.second;
+}
+
+void TSymbolTable::TSymbolTableLevel::insertUnmangled(TFunction *function)
+{
+ level.insert(tLevelPair(function->name(), function));
+}
+
+TSymbol *TSymbolTable::TSymbolTableLevel::find(const ImmutableString &name) const
+{
+ tLevel::const_iterator it = level.find(name);
+ if (it == level.end())
+ return nullptr;
+ else
+ return (*it).second;
+}
+
+TSymbolTable::TSymbolTable()
+ : mGlobalInvariant(false),
+ mUniqueIdCounter(0),
+ mShaderType(GL_FRAGMENT_SHADER),
+ mShaderSpec(SH_GLES2_SPEC),
+ mGlInVariableWithArraySize(nullptr)
+{}
+
+TSymbolTable::~TSymbolTable() = default;
+
+bool TSymbolTable::isEmpty() const
+{
+ return mTable.empty();
+}
+
+bool TSymbolTable::atGlobalLevel() const
+{
+ return mTable.size() == 1u;
+}
+
+void TSymbolTable::push()
+{
+ mTable.emplace_back(new TSymbolTableLevel);
+ mPrecisionStack.emplace_back(new PrecisionStackLevel);
+}
+
+void TSymbolTable::pop()
+{
+ mTable.pop_back();
+ mPrecisionStack.pop_back();
+}
+
+const TFunction *TSymbolTable::markFunctionHasPrototypeDeclaration(
+ const ImmutableString &mangledName,
+ bool *hadPrototypeDeclarationOut) const
+{
+ TFunction *function = findUserDefinedFunction(mangledName);
+ *hadPrototypeDeclarationOut = function->hasPrototypeDeclaration();
+ function->setHasPrototypeDeclaration();
+ return function;
+}
+
+const TFunction *TSymbolTable::setFunctionParameterNamesFromDefinition(const TFunction *function,
+ bool *wasDefinedOut) const
+{
+ TFunction *firstDeclaration = findUserDefinedFunction(function->getMangledName());
+ ASSERT(firstDeclaration);
+ // Note: 'firstDeclaration' could be 'function' if this is the first time we've seen function as
+ // it would have just been put in the symbol table. Otherwise, we're looking up an earlier
+ // occurance.
+ if (function != firstDeclaration)
+ {
+ // The previous declaration should have the same parameters as the function definition
+ // (parameter names may differ).
+ firstDeclaration->shareParameters(*function);
+ }
+
+ *wasDefinedOut = firstDeclaration->isDefined();
+ firstDeclaration->setDefined();
+ return firstDeclaration;
+}
+
+bool TSymbolTable::setGlInArraySize(unsigned int inputArraySize)
+{
+ if (mGlInVariableWithArraySize)
+ {
+ return mGlInVariableWithArraySize->getType().getOutermostArraySize() == inputArraySize;
+ }
+ const TInterfaceBlock *glPerVertex = static_cast<const TInterfaceBlock *>(m_gl_PerVertex);
+ TType *glInType = new TType(glPerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ glInType->makeArray(inputArraySize);
+ mGlInVariableWithArraySize =
+ new TVariable(this, ImmutableString("gl_in"), glInType, SymbolType::BuiltIn,
+ TExtension::EXT_geometry_shader);
+ return true;
+}
+
+TVariable *TSymbolTable::getGlInVariableWithArraySize() const
+{
+ return mGlInVariableWithArraySize;
+}
+
+const TVariable *TSymbolTable::gl_FragData() const
+{
+ return static_cast<const TVariable *>(m_gl_FragData);
+}
+
+const TVariable *TSymbolTable::gl_SecondaryFragDataEXT() const
+{
+ return static_cast<const TVariable *>(m_gl_SecondaryFragDataEXT);
+}
+
+TSymbolTable::VariableMetadata *TSymbolTable::getOrCreateVariableMetadata(const TVariable &variable)
+{
+ int id = variable.uniqueId().get();
+ auto iter = mVariableMetadata.find(id);
+ if (iter == mVariableMetadata.end())
+ {
+ iter = mVariableMetadata.insert(std::make_pair(id, VariableMetadata())).first;
+ }
+ return &iter->second;
+}
+
+void TSymbolTable::markStaticWrite(const TVariable &variable)
+{
+ auto metadata = getOrCreateVariableMetadata(variable);
+ metadata->staticWrite = true;
+}
+
+void TSymbolTable::markStaticRead(const TVariable &variable)
+{
+ auto metadata = getOrCreateVariableMetadata(variable);
+ metadata->staticRead = true;
+}
+
+bool TSymbolTable::isStaticallyUsed(const TVariable &variable) const
+{
+ ASSERT(!variable.getConstPointer());
+ int id = variable.uniqueId().get();
+ auto iter = mVariableMetadata.find(id);
+ return iter != mVariableMetadata.end() && (iter->second.staticRead || iter->second.staticWrite);
+}
+
+void TSymbolTable::addInvariantVarying(const TVariable &variable)
+{
+ ASSERT(atGlobalLevel());
+ auto metadata = getOrCreateVariableMetadata(variable);
+ metadata->invariant = true;
+}
+
+bool TSymbolTable::isVaryingInvariant(const TVariable &variable) const
+{
+ ASSERT(atGlobalLevel());
+ if (mGlobalInvariant && (IsShaderOutput(variable.getType().getQualifier())))
+ {
+ return true;
+ }
+ int id = variable.uniqueId().get();
+ auto iter = mVariableMetadata.find(id);
+ return iter != mVariableMetadata.end() && iter->second.invariant;
+}
+
+void TSymbolTable::setGlobalInvariant(bool invariant)
+{
+ ASSERT(atGlobalLevel());
+ mGlobalInvariant = invariant;
+}
+
+const TSymbol *TSymbolTable::find(const ImmutableString &name, int shaderVersion) const
+{
+ const TSymbol *userSymbol = findUserDefined(name);
+ if (userSymbol)
+ {
+ return userSymbol;
+ }
+
+ return findBuiltIn(name, shaderVersion);
+}
+
+const TSymbol *TSymbolTable::findUserDefined(const ImmutableString &name) const
+{
+ int userDefinedLevel = static_cast<int>(mTable.size()) - 1;
+ while (userDefinedLevel >= 0)
+ {
+ const TSymbol *symbol = mTable[userDefinedLevel]->find(name);
+ if (symbol)
+ {
+ return symbol;
+ }
+ userDefinedLevel--;
+ }
+
+ return nullptr;
+}
+
+TFunction *TSymbolTable::findUserDefinedFunction(const ImmutableString &name) const
+{
+ // User-defined functions are always declared at the global level.
+ ASSERT(!mTable.empty());
+ return static_cast<TFunction *>(mTable[0]->find(name));
+}
+
+const TSymbol *TSymbolTable::findGlobal(const ImmutableString &name) const
+{
+ ASSERT(!mTable.empty());
+ return mTable[0]->find(name);
+}
+
+const TSymbol *TSymbolTable::findGlobalWithConversion(
+ const std::vector<ImmutableString> &names) const
+{
+ for (const ImmutableString &name : names)
+ {
+ const TSymbol *target = findGlobal(name);
+ if (target != nullptr)
+ return target;
+ }
+ return nullptr;
+}
+
+const TSymbol *TSymbolTable::findBuiltInWithConversion(const std::vector<ImmutableString> &names,
+ int shaderVersion) const
+{
+ for (const ImmutableString &name : names)
+ {
+ const TSymbol *target = findBuiltIn(name, shaderVersion);
+ if (target != nullptr)
+ return target;
+ }
+ return nullptr;
+}
+
+bool TSymbolTable::declare(TSymbol *symbol)
+{
+ ASSERT(!mTable.empty());
+ // The following built-ins may be redeclared by the shader: gl_ClipDistance, gl_CullDistance and
+ // gl_LastFragData.
+ ASSERT(symbol->symbolType() == SymbolType::UserDefined ||
+ (symbol->symbolType() == SymbolType::BuiltIn && IsRedeclarableBuiltIn(symbol->name())));
+ ASSERT(!symbol->isFunction());
+ return mTable.back()->insert(symbol);
+}
+
+bool TSymbolTable::declareInternal(TSymbol *symbol)
+{
+ ASSERT(!mTable.empty());
+ ASSERT(symbol->symbolType() == SymbolType::AngleInternal);
+ ASSERT(!symbol->isFunction());
+ return mTable.back()->insert(symbol);
+}
+
+void TSymbolTable::declareUserDefinedFunction(TFunction *function, bool insertUnmangledName)
+{
+ ASSERT(!mTable.empty());
+ if (insertUnmangledName)
+ {
+ // Insert the unmangled name to detect potential future redefinition as a variable.
+ mTable[0]->insertUnmangled(function);
+ }
+ mTable[0]->insert(function);
+}
+
+void TSymbolTable::setDefaultPrecision(TBasicType type, TPrecision prec)
+{
+ int indexOfLastElement = static_cast<int>(mPrecisionStack.size()) - 1;
+ // Uses map operator [], overwrites the current value
+ (*mPrecisionStack[indexOfLastElement])[type] = prec;
+}
+
+TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
+{
+ if (!SupportsPrecision(type))
+ return EbpUndefined;
+
+ // unsigned integers use the same precision as signed
+ TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
+
+ int level = static_cast<int>(mPrecisionStack.size()) - 1;
+ ASSERT(level >= 0); // Just to be safe. Should not happen.
+ // If we dont find anything we return this. Some types don't have predefined default precision.
+ TPrecision prec = EbpUndefined;
+ while (level >= 0)
+ {
+ PrecisionStackLevel::iterator it = mPrecisionStack[level]->find(baseType);
+ if (it != mPrecisionStack[level]->end())
+ {
+ prec = (*it).second;
+ break;
+ }
+ level--;
+ }
+ return prec;
+}
+
+void TSymbolTable::clearCompilationResults()
+{
+ mGlobalInvariant = false;
+ mUniqueIdCounter = kLastBuiltInId + 1;
+ mVariableMetadata.clear();
+ mGlInVariableWithArraySize = nullptr;
+
+ // User-defined scopes should have already been cleared when the compilation finished.
+ ASSERT(mTable.empty());
+}
+
+int TSymbolTable::nextUniqueIdValue()
+{
+ ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
+ return ++mUniqueIdCounter;
+}
+
+void TSymbolTable::initializeBuiltIns(sh::GLenum type,
+ ShShaderSpec spec,
+ const ShBuiltInResources &resources)
+{
+ mShaderType = type;
+ mShaderSpec = spec;
+ mResources = resources;
+
+ // We need just one precision stack level for predefined precisions.
+ mPrecisionStack.emplace_back(new PrecisionStackLevel);
+
+ if (IsDesktopGLSpec(spec))
+ {
+ setDefaultPrecision(EbtInt, EbpUndefined);
+ setDefaultPrecision(EbtFloat, EbpUndefined);
+ }
+ else
+ {
+ switch (type)
+ {
+ case GL_FRAGMENT_SHADER:
+ setDefaultPrecision(EbtInt, EbpMedium);
+ break;
+ case GL_VERTEX_SHADER:
+ case GL_COMPUTE_SHADER:
+ case GL_GEOMETRY_SHADER_EXT:
+ case GL_TESS_CONTROL_SHADER_EXT:
+ case GL_TESS_EVALUATION_SHADER_EXT:
+ setDefaultPrecision(EbtInt, EbpHigh);
+ setDefaultPrecision(EbtFloat, EbpHigh);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ // Set defaults for sampler types that have default precision, even those that are
+ // only available if an extension exists.
+ // New sampler types in ESSL3 don't have default precision. ESSL1 types do.
+ initSamplerDefaultPrecision(EbtSampler2D);
+ initSamplerDefaultPrecision(EbtSamplerCube);
+ // SamplerExternalOES is specified in the extension to have default precision.
+ initSamplerDefaultPrecision(EbtSamplerExternalOES);
+ // SamplerExternal2DY2YEXT is specified in the extension to have default precision.
+ initSamplerDefaultPrecision(EbtSamplerExternal2DY2YEXT);
+ // It isn't specified whether Sampler2DRect has default precision.
+ initSamplerDefaultPrecision(EbtSampler2DRect);
+
+ if (spec < SH_GLES3_SPEC)
+ {
+ // Only set the default precision of shadow samplers in ESLL1. They become core in ESSL3
+ // where they do not have a defalut precision.
+ initSamplerDefaultPrecision(EbtSampler2DShadow);
+ }
+
+ setDefaultPrecision(EbtAtomicCounter, EbpHigh);
+
+ initializeBuiltInVariables(type, spec, resources);
+ mUniqueIdCounter = kLastBuiltInId + 1;
+}
+
+void TSymbolTable::initSamplerDefaultPrecision(TBasicType samplerType)
+{
+ ASSERT(samplerType >= EbtGuardSamplerBegin && samplerType <= EbtGuardSamplerEnd);
+ setDefaultPrecision(samplerType, EbpLow);
+}
+
+TSymbolTable::VariableMetadata::VariableMetadata()
+ : staticRead(false), staticWrite(false), invariant(false)
+{}
+
+const TSymbol *SymbolRule::get(ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const ShBuiltInResources &resources,
+ const TSymbolTableBase &symbolTable) const
+{
+ if (IsDesktopGLSpec(shaderSpec) != (mIsDesktop == 1))
+ return nullptr;
+
+ if (mVersion == kESSL1Only && shaderVersion != static_cast<int>(kESSL1Only))
+ return nullptr;
+
+ if (mVersion > shaderVersion)
+ return nullptr;
+
+ if (!CheckShaderType(static_cast<Shader>(mShaders), shaderType))
+ return nullptr;
+
+ if (mExtensionIndex != 0 && !CheckExtension(mExtensionIndex, resources))
+ return nullptr;
+
+ return mIsVar > 0 ? symbolTable.*(mSymbolOrVar.var) : mSymbolOrVar.symbol;
+}
+
+const TSymbol *FindMangledBuiltIn(ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const ShBuiltInResources &resources,
+ const TSymbolTableBase &symbolTable,
+ const SymbolRule *rules,
+ uint16_t startIndex,
+ uint16_t endIndex)
+{
+ for (uint32_t ruleIndex = startIndex; ruleIndex < endIndex; ++ruleIndex)
+ {
+ const TSymbol *symbol =
+ rules[ruleIndex].get(shaderSpec, shaderVersion, shaderType, resources, symbolTable);
+ if (symbol)
+ {
+ return symbol;
+ }
+ }
+
+ return nullptr;
+}
+
+bool UnmangledEntry::matches(const ImmutableString &name,
+ ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const TExtensionBehavior &extensions) const
+{
+ if (name != mName)
+ return false;
+
+ if (!CheckShaderType(static_cast<Shader>(mShaderType), shaderType))
+ return false;
+
+ if (IsDesktopGLSpec(shaderSpec))
+ {
+ if (mGLSLVersion > shaderVersion)
+ return false;
+
+ if (mGLSLExtension == TExtension::UNDEFINED)
+ return true;
+
+ return IsExtensionEnabled(extensions, mGLSLExtension);
+ }
+ else
+ {
+ if (mESSLVersion == kESSL1Only && shaderVersion != static_cast<int>(kESSL1Only))
+ return false;
+
+ if (mESSLVersion > shaderVersion)
+ return false;
+
+ bool anyExtension = false;
+ bool anyExtensionEnabled = false;
+ for (TExtension ext : mESSLExtensions)
+ {
+ if (ext != TExtension::UNDEFINED)
+ {
+ anyExtension = true;
+ anyExtensionEnabled = anyExtensionEnabled || IsExtensionEnabled(extensions, ext);
+ }
+ }
+
+ if (!anyExtension)
+ return true;
+
+ return anyExtensionEnabled;
+ }
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolTable.h b/gfx/angle/checkout/src/compiler/translator/SymbolTable.h
new file mode 100644
index 0000000000..fb05729981
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable.h
@@ -0,0 +1,363 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_SYMBOLTABLE_H_
+#define COMPILER_TRANSLATOR_SYMBOLTABLE_H_
+
+//
+// Symbol table for parsing. Has these design characteristics:
+//
+// * Same symbol table can be used to compile many shaders, to preserve
+// effort of creating and loading with the large numbers of built-in
+// symbols.
+//
+// * Name mangling will be used to give each function a unique name
+// so that symbol table lookups are never ambiguous. This allows
+// a simpler symbol table structure.
+//
+// * Pushing and popping of scope, so symbol table will really be a stack
+// of symbol tables. Searched from the top, with new inserts going into
+// the top.
+//
+// * Constants: Compile time constant symbols will keep their values
+// in the symbol table. The parser can substitute constants at parse
+// time, including doing constant folding and constant propagation.
+//
+// * No temporaries: Temporaries made from operations (+, --, .xy, etc.)
+// are tracked in the intermediate representation, not the symbol table.
+//
+
+#include <limits>
+#include <memory>
+#include <set>
+
+#include "common/angleutils.h"
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable_autogen.h"
+
+enum class Shader : uint8_t
+{
+ ALL,
+ FRAGMENT, // GL_FRAGMENT_SHADER
+ VERTEX, // GL_VERTEX_SHADER
+ COMPUTE, // GL_COMPUTE_SHADER
+ GEOMETRY, // GL_GEOMETRY_SHADER
+ GEOMETRY_EXT, // GL_GEOMETRY_SHADER_EXT
+ TESS_CONTROL_EXT, // GL_TESS_CONTROL_SHADER_EXT
+ TESS_EVALUATION_EXT, // GL_TESS_EVALUATION_SHADER_EXT
+ NOT_COMPUTE
+};
+
+namespace sh
+{
+
+struct UnmangledBuiltIn
+{
+ constexpr UnmangledBuiltIn(TExtension extension) : extension(extension) {}
+
+ TExtension extension;
+};
+
+using VarPointer = TSymbol *(TSymbolTableBase::*);
+using ValidateExtension = int ShBuiltInResources::*;
+
+enum class Spec : uint8_t
+{
+ GLSL,
+ ESSL
+};
+
+constexpr uint16_t kESSL1Only = 100;
+// Some built-ins from backend shader languages are made available internally to ESSL for use in
+// tree transformations. This (invalid) shader version is used to select those built-ins. This
+// value needs to be larger than all other shader versions.
+constexpr uint16_t kESSLInternalBackendBuiltIns = 0x3FFF;
+
+// The version assigned to |kESSLInternalBackendBuiltIns| should be good until OpenGL 20.0!
+static_assert(kESSLInternalBackendBuiltIns > 2000,
+ "Accidentally exposing internal backend built-ins in OpenGL");
+
+static_assert(offsetof(ShBuiltInResources, OES_standard_derivatives) != 0,
+ "Update SymbolTable extension logic");
+
+#define EXT_INDEX(Ext) (offsetof(ShBuiltInResources, Ext) / sizeof(int))
+
+class SymbolRule
+{
+ public:
+ const TSymbol *get(ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const ShBuiltInResources &resources,
+ const TSymbolTableBase &symbolTable) const;
+
+ template <Spec spec, int version, Shader shaders, size_t extensionIndex, typename T>
+ constexpr static SymbolRule Get(T value);
+
+ private:
+ constexpr SymbolRule(Spec spec,
+ int version,
+ Shader shaders,
+ size_t extensionIndex,
+ const TSymbol *symbol);
+
+ constexpr SymbolRule(Spec spec,
+ int version,
+ Shader shaders,
+ size_t extensionIndex,
+ VarPointer resourceVar);
+
+ union SymbolOrVar
+ {
+ constexpr SymbolOrVar(const TSymbol *symbolIn) : symbol(symbolIn) {}
+ constexpr SymbolOrVar(VarPointer varIn) : var(varIn) {}
+
+ const TSymbol *symbol;
+ VarPointer var;
+ };
+
+ uint16_t mIsDesktop : 1;
+ uint16_t mIsVar : 1;
+ uint16_t mVersion : 14;
+ uint8_t mShaders;
+ uint8_t mExtensionIndex;
+ SymbolOrVar mSymbolOrVar;
+};
+
+constexpr SymbolRule::SymbolRule(Spec spec,
+ int version,
+ Shader shaders,
+ size_t extensionIndex,
+ const TSymbol *symbol)
+ : mIsDesktop(spec == Spec::GLSL ? 1u : 0u),
+ mIsVar(0u),
+ mVersion(static_cast<uint16_t>(version)),
+ mShaders(static_cast<uint8_t>(shaders)),
+ mExtensionIndex(extensionIndex),
+ mSymbolOrVar(symbol)
+{}
+
+constexpr SymbolRule::SymbolRule(Spec spec,
+ int version,
+ Shader shaders,
+ size_t extensionIndex,
+ VarPointer resourceVar)
+ : mIsDesktop(spec == Spec::GLSL ? 1u : 0u),
+ mIsVar(1u),
+ mVersion(static_cast<uint16_t>(version)),
+ mShaders(static_cast<uint8_t>(shaders)),
+ mExtensionIndex(extensionIndex),
+ mSymbolOrVar(resourceVar)
+{}
+
+template <Spec spec, int version, Shader shaders, size_t extensionIndex, typename T>
+// static
+constexpr SymbolRule SymbolRule::Get(T value)
+{
+ static_assert(version < 0x4000u, "version OOR");
+ static_assert(static_cast<uint8_t>(shaders) < 0xFFu, "shaders OOR");
+ static_assert(static_cast<uint8_t>(extensionIndex) < 0xFF, "extensionIndex OOR");
+ return SymbolRule(spec, version, shaders, extensionIndex, value);
+}
+
+const TSymbol *FindMangledBuiltIn(ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const ShBuiltInResources &resources,
+ const TSymbolTableBase &symbolTable,
+ const SymbolRule *rules,
+ uint16_t startIndex,
+ uint16_t endIndex);
+
+class UnmangledEntry
+{
+ public:
+ template <size_t ESSLExtCount>
+ constexpr UnmangledEntry(const char *name,
+ const std::array<TExtension, ESSLExtCount> &esslExtensions,
+ TExtension glslExtension,
+ int esslVersion,
+ int glslVersion,
+ Shader shaderType);
+
+ bool matches(const ImmutableString &name,
+ ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const TExtensionBehavior &extensions) const;
+
+ private:
+ const char *mName;
+ std::array<TExtension, 2u> mESSLExtensions;
+ TExtension mGLSLExtension;
+ uint8_t mShaderType;
+ uint16_t mESSLVersion;
+ uint16_t mGLSLVersion;
+};
+
+template <size_t ESSLExtCount>
+constexpr UnmangledEntry::UnmangledEntry(const char *name,
+ const std::array<TExtension, ESSLExtCount> &esslExtensions,
+ TExtension glslExtension,
+ int esslVersion,
+ int glslVersion,
+ Shader shaderType)
+ : mName(name),
+ mESSLExtensions{(ESSLExtCount >= 1) ? esslExtensions[0] : TExtension::UNDEFINED,
+ (ESSLExtCount >= 2) ? esslExtensions[1] : TExtension::UNDEFINED},
+ mGLSLExtension(glslExtension),
+ mShaderType(static_cast<uint8_t>(shaderType)),
+ mESSLVersion(esslVersion < 0 ? std::numeric_limits<uint16_t>::max()
+ : static_cast<uint16_t>(esslVersion)),
+ mGLSLVersion(glslVersion < 0 ? std::numeric_limits<uint16_t>::max()
+ : static_cast<uint16_t>(glslVersion))
+{}
+
+class TSymbolTable : angle::NonCopyable, TSymbolTableBase
+{
+ public:
+ TSymbolTable();
+ // To start using the symbol table after construction:
+ // * initializeBuiltIns() needs to be called.
+ // * push() needs to be called to push the global level.
+
+ ~TSymbolTable();
+
+ bool isEmpty() const;
+ bool atGlobalLevel() const;
+
+ void push();
+ void pop();
+
+ // Declare a non-function symbol at the current scope. Return true in case the declaration was
+ // successful, and false if the declaration failed due to redefinition.
+ bool declare(TSymbol *symbol);
+
+ // Only used to declare internal variables.
+ bool declareInternal(TSymbol *symbol);
+
+ // Functions are always declared at global scope.
+ void declareUserDefinedFunction(TFunction *function, bool insertUnmangledName);
+
+ // These return the TFunction pointer to keep using to refer to this function.
+ const TFunction *markFunctionHasPrototypeDeclaration(const ImmutableString &mangledName,
+ bool *hadPrototypeDeclarationOut) const;
+ const TFunction *setFunctionParameterNamesFromDefinition(const TFunction *function,
+ bool *wasDefinedOut) const;
+
+ // Return false if the gl_in array size has already been initialized with a mismatching value.
+ bool setGlInArraySize(unsigned int inputArraySize);
+ TVariable *getGlInVariableWithArraySize() const;
+
+ const TVariable *gl_FragData() const;
+ const TVariable *gl_SecondaryFragDataEXT() const;
+
+ void markStaticRead(const TVariable &variable);
+ void markStaticWrite(const TVariable &variable);
+
+ // Note: Should not call this for constant variables.
+ bool isStaticallyUsed(const TVariable &variable) const;
+
+ // find() is guaranteed not to retain a reference to the ImmutableString, so an ImmutableString
+ // with a reference to a short-lived char * is fine to pass here.
+ const TSymbol *find(const ImmutableString &name, int shaderVersion) const;
+
+ const TSymbol *findUserDefined(const ImmutableString &name) const;
+
+ TFunction *findUserDefinedFunction(const ImmutableString &name) const;
+
+ const TSymbol *findGlobal(const ImmutableString &name) const;
+ const TSymbol *findGlobalWithConversion(const std::vector<ImmutableString> &names) const;
+
+ const TSymbol *findBuiltIn(const ImmutableString &name, int shaderVersion) const;
+ const TSymbol *findBuiltInWithConversion(const std::vector<ImmutableString> &names,
+ int shaderVersion) const;
+
+ void setDefaultPrecision(TBasicType type, TPrecision prec);
+
+ // Searches down the precisionStack for a precision qualifier
+ // for the specified TBasicType
+ TPrecision getDefaultPrecision(TBasicType type) const;
+
+ // This records invariant varyings declared through "invariant varying_name;".
+ void addInvariantVarying(const TVariable &variable);
+
+ // If this returns false, the varying could still be invariant if it is set as invariant during
+ // the varying variable declaration - this piece of information is stored in the variable's
+ // type, not here.
+ bool isVaryingInvariant(const TVariable &variable) const;
+
+ void setGlobalInvariant(bool invariant);
+
+ const TSymbolUniqueId nextUniqueId() { return TSymbolUniqueId(this); }
+
+ // Gets the built-in accessible by a shader with the specified version, if any.
+ bool isUnmangledBuiltInName(const ImmutableString &name,
+ int shaderVersion,
+ const TExtensionBehavior &extensions) const;
+
+ void initializeBuiltIns(sh::GLenum type,
+ ShShaderSpec spec,
+ const ShBuiltInResources &resources);
+ void clearCompilationResults();
+
+ ShShaderSpec getShaderSpec() const { return mShaderSpec; }
+
+ private:
+ friend class TSymbolUniqueId;
+
+ struct VariableMetadata
+ {
+ VariableMetadata();
+ bool staticRead;
+ bool staticWrite;
+ bool invariant;
+ };
+
+ int nextUniqueIdValue();
+
+ class TSymbolTableLevel;
+
+ void initSamplerDefaultPrecision(TBasicType samplerType);
+
+ void initializeBuiltInVariables(sh::GLenum shaderType,
+ ShShaderSpec spec,
+ const ShBuiltInResources &resources);
+
+ VariableMetadata *getOrCreateVariableMetadata(const TVariable &variable);
+
+ std::vector<std::unique_ptr<TSymbolTableLevel>> mTable;
+
+ // There's one precision stack level for predefined precisions and then one level for each scope
+ // in table.
+ typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
+ std::vector<std::unique_ptr<PrecisionStackLevel>> mPrecisionStack;
+
+ bool mGlobalInvariant;
+
+ int mUniqueIdCounter;
+
+ static const int kLastBuiltInId;
+
+ sh::GLenum mShaderType;
+ ShShaderSpec mShaderSpec;
+ ShBuiltInResources mResources;
+
+ // Indexed by unique id. Map instead of vector since the variables are fairly sparse.
+ std::map<int, VariableMetadata> mVariableMetadata;
+
+ // Store gl_in variable with its array size once the array size can be determined. The array
+ // size can also be checked against latter input primitive type declaration.
+ TVariable *mGlInVariableWithArraySize;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SYMBOLTABLE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolTable_ESSL_autogen.cpp b/gfx/angle/checkout/src/compiler/translator/SymbolTable_ESSL_autogen.cpp
new file mode 100644
index 0000000000..483e9b4748
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable_ESSL_autogen.cpp
@@ -0,0 +1,30071 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SymbolTable_ESSL_autogen.cpp:
+// Compile-time initialized built-ins.
+
+#include <cmath>
+
+#include "compiler/translator/SymbolTable.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+
+namespace sh
+{
+using Resources = ShBuiltInResources;
+using TableBase = TSymbolTableBase;
+
+const int TSymbolTable::kLastBuiltInId = 5603;
+
+namespace BuiltInName
+{
+
+constexpr const ImmutableString _empty("");
+constexpr const ImmutableString EmitVertex("EmitVertex");
+constexpr const ImmutableString EmitVertexES3_2("EmitVertex");
+constexpr const ImmutableString EndPrimitive("EndPrimitive");
+constexpr const ImmutableString EndPrimitiveES3_2("EndPrimitive");
+constexpr const ImmutableString abs("abs");
+constexpr const ImmutableString acos("acos");
+constexpr const ImmutableString acosh("acosh");
+constexpr const ImmutableString all("all");
+constexpr const ImmutableString angle_BaseInstance("angle_BaseInstance");
+constexpr const ImmutableString angle_BaseVertex("angle_BaseVertex");
+constexpr const ImmutableString any("any");
+constexpr const ImmutableString asin("asin");
+constexpr const ImmutableString asinh("asinh");
+constexpr const ImmutableString atan("atan");
+constexpr const ImmutableString atanh("atanh");
+constexpr const ImmutableString atomicAdd("atomicAdd");
+constexpr const ImmutableString atomicAnd("atomicAnd");
+constexpr const ImmutableString atomicCompSwap("atomicCompSwap");
+constexpr const ImmutableString atomicCounter("atomicCounter");
+constexpr const ImmutableString atomicCounterDecrement("atomicCounterDecrement");
+constexpr const ImmutableString atomicCounterIncrement("atomicCounterIncrement");
+constexpr const ImmutableString atomicExchange("atomicExchange");
+constexpr const ImmutableString atomicMax("atomicMax");
+constexpr const ImmutableString atomicMin("atomicMin");
+constexpr const ImmutableString atomicOr("atomicOr");
+constexpr const ImmutableString atomicXor("atomicXor");
+constexpr const ImmutableString barrier("barrier");
+constexpr const ImmutableString barrierTCS("barrier");
+constexpr const ImmutableString barrierTCSES3_2("barrier");
+constexpr const ImmutableString beginFragmentShaderOrderingINTEL(
+ "beginFragmentShaderOrderingINTEL");
+constexpr const ImmutableString beginInvocationInterlockARB("beginInvocationInterlockARB");
+constexpr const ImmutableString beginInvocationInterlockNV("beginInvocationInterlockNV");
+constexpr const ImmutableString bitCount("bitCount");
+constexpr const ImmutableString bitfieldExtract("bitfieldExtract");
+constexpr const ImmutableString bitfieldInsert("bitfieldInsert");
+constexpr const ImmutableString bitfieldReverse("bitfieldReverse");
+constexpr const ImmutableString ceil("ceil");
+constexpr const ImmutableString clamp("clamp");
+constexpr const ImmutableString cos("cos");
+constexpr const ImmutableString cosh("cosh");
+constexpr const ImmutableString cross("cross");
+constexpr const ImmutableString dFdx("dFdx");
+constexpr const ImmutableString dFdxExt("dFdx");
+constexpr const ImmutableString dFdy("dFdy");
+constexpr const ImmutableString dFdyExt("dFdy");
+constexpr const ImmutableString degrees("degrees");
+constexpr const ImmutableString determinant("determinant");
+constexpr const ImmutableString diff("diff");
+constexpr const ImmutableString distance("distance");
+constexpr const ImmutableString dot("dot");
+constexpr const ImmutableString endInvocationInterlockARB("endInvocationInterlockARB");
+constexpr const ImmutableString endInvocationInterlockNV("endInvocationInterlockNV");
+constexpr const ImmutableString equal("equal");
+constexpr const ImmutableString exp("exp");
+constexpr const ImmutableString exp2("exp2");
+constexpr const ImmutableString faceforward("faceforward");
+constexpr const ImmutableString far("far");
+constexpr const ImmutableString findLSB("findLSB");
+constexpr const ImmutableString findMSB("findMSB");
+constexpr const ImmutableString floatBitsToInt("floatBitsToInt");
+constexpr const ImmutableString floatBitsToUint("floatBitsToUint");
+constexpr const ImmutableString floor("floor");
+constexpr const ImmutableString fma("fma");
+constexpr const ImmutableString fmaExt("fma");
+constexpr const ImmutableString fract("fract");
+constexpr const ImmutableString frexp("frexp");
+constexpr const ImmutableString fwidth("fwidth");
+constexpr const ImmutableString fwidthExt("fwidth");
+constexpr const ImmutableString gl_BaseInstance("gl_BaseInstance");
+constexpr const ImmutableString gl_BaseVertex("gl_BaseVertex");
+constexpr const ImmutableString gl_BoundingBox("gl_BoundingBox");
+constexpr const ImmutableString gl_BoundingBoxEXT("gl_BoundingBoxEXT");
+constexpr const ImmutableString gl_BoundingBoxOES("gl_BoundingBoxOES");
+constexpr const ImmutableString gl_ClipDistance("gl_ClipDistance");
+constexpr const ImmutableString gl_CullDistance("gl_CullDistance");
+constexpr const ImmutableString gl_DepthRange("gl_DepthRange");
+constexpr const ImmutableString gl_DepthRangeParameters("gl_DepthRangeParameters");
+constexpr const ImmutableString gl_DrawID("gl_DrawID");
+constexpr const ImmutableString gl_FragColor("gl_FragColor");
+constexpr const ImmutableString gl_FragCoord("gl_FragCoord");
+constexpr const ImmutableString gl_FragData("gl_FragData");
+constexpr const ImmutableString gl_FragDepth("gl_FragDepth");
+constexpr const ImmutableString gl_FragDepthEXT("gl_FragDepthEXT");
+constexpr const ImmutableString gl_FrontFacing("gl_FrontFacing");
+constexpr const ImmutableString gl_GlobalInvocationID("gl_GlobalInvocationID");
+constexpr const ImmutableString gl_HelperInvocation("gl_HelperInvocation");
+constexpr const ImmutableString gl_InstanceID("gl_InstanceID");
+constexpr const ImmutableString gl_InstanceIndex("gl_InstanceIndex");
+constexpr const ImmutableString gl_InvocationID("gl_InvocationID");
+constexpr const ImmutableString gl_LastFragColor("gl_LastFragColor");
+constexpr const ImmutableString gl_LastFragColorARM("gl_LastFragColorARM");
+constexpr const ImmutableString gl_LastFragData("gl_LastFragData");
+constexpr const ImmutableString gl_Layer("gl_Layer");
+constexpr const ImmutableString gl_LocalInvocationID("gl_LocalInvocationID");
+constexpr const ImmutableString gl_LocalInvocationIndex("gl_LocalInvocationIndex");
+constexpr const ImmutableString gl_MaxAtomicCounterBindings("gl_MaxAtomicCounterBindings");
+constexpr const ImmutableString gl_MaxAtomicCounterBufferSize("gl_MaxAtomicCounterBufferSize");
+constexpr const ImmutableString gl_MaxClipDistances("gl_MaxClipDistances");
+constexpr const ImmutableString gl_MaxCombinedAtomicCounterBuffers(
+ "gl_MaxCombinedAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxCombinedAtomicCounters("gl_MaxCombinedAtomicCounters");
+constexpr const ImmutableString gl_MaxCombinedClipAndCullDistances(
+ "gl_MaxCombinedClipAndCullDistances");
+constexpr const ImmutableString gl_MaxCombinedImageUniforms("gl_MaxCombinedImageUniforms");
+constexpr const ImmutableString gl_MaxCombinedShaderOutputResources(
+ "gl_MaxCombinedShaderOutputResources");
+constexpr const ImmutableString gl_MaxCombinedTextureImageUnits("gl_MaxCombinedTextureImageUnits");
+constexpr const ImmutableString gl_MaxComputeAtomicCounterBuffers(
+ "gl_MaxComputeAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxComputeAtomicCounters("gl_MaxComputeAtomicCounters");
+constexpr const ImmutableString gl_MaxComputeImageUniforms("gl_MaxComputeImageUniforms");
+constexpr const ImmutableString gl_MaxComputeTextureImageUnits("gl_MaxComputeTextureImageUnits");
+constexpr const ImmutableString gl_MaxComputeUniformComponents("gl_MaxComputeUniformComponents");
+constexpr const ImmutableString gl_MaxComputeWorkGroupCount("gl_MaxComputeWorkGroupCount");
+constexpr const ImmutableString gl_MaxComputeWorkGroupSize("gl_MaxComputeWorkGroupSize");
+constexpr const ImmutableString gl_MaxCullDistances("gl_MaxCullDistances");
+constexpr const ImmutableString gl_MaxDrawBuffers("gl_MaxDrawBuffers");
+constexpr const ImmutableString gl_MaxDualSourceDrawBuffersEXT("gl_MaxDualSourceDrawBuffersEXT");
+constexpr const ImmutableString gl_MaxFragmentAtomicCounterBuffers(
+ "gl_MaxFragmentAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxFragmentAtomicCounters("gl_MaxFragmentAtomicCounters");
+constexpr const ImmutableString gl_MaxFragmentImageUniforms("gl_MaxFragmentImageUniforms");
+constexpr const ImmutableString gl_MaxFragmentInputVectors("gl_MaxFragmentInputVectors");
+constexpr const ImmutableString gl_MaxFragmentUniformVectors("gl_MaxFragmentUniformVectors");
+constexpr const ImmutableString gl_MaxGeometryAtomicCounterBuffers(
+ "gl_MaxGeometryAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxGeometryAtomicCounters("gl_MaxGeometryAtomicCounters");
+constexpr const ImmutableString gl_MaxGeometryImageUniforms("gl_MaxGeometryImageUniforms");
+constexpr const ImmutableString gl_MaxGeometryInputComponents("gl_MaxGeometryInputComponents");
+constexpr const ImmutableString gl_MaxGeometryOutputComponents("gl_MaxGeometryOutputComponents");
+constexpr const ImmutableString gl_MaxGeometryOutputVertices("gl_MaxGeometryOutputVertices");
+constexpr const ImmutableString gl_MaxGeometryTextureImageUnits("gl_MaxGeometryTextureImageUnits");
+constexpr const ImmutableString gl_MaxGeometryTotalOutputComponents(
+ "gl_MaxGeometryTotalOutputComponents");
+constexpr const ImmutableString gl_MaxGeometryUniformComponents("gl_MaxGeometryUniformComponents");
+constexpr const ImmutableString gl_MaxImageUnits("gl_MaxImageUnits");
+constexpr const ImmutableString gl_MaxPatchVertices("gl_MaxPatchVertices");
+constexpr const ImmutableString gl_MaxProgramTexelOffset("gl_MaxProgramTexelOffset");
+constexpr const ImmutableString gl_MaxSamples("gl_MaxSamples");
+constexpr const ImmutableString gl_MaxTessControlAtomicCounterBuffers(
+ "gl_MaxTessControlAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxTessControlAtomicCounters("gl_MaxTessControlAtomicCounters");
+constexpr const ImmutableString gl_MaxTessControlImageUniforms("gl_MaxTessControlImageUniforms");
+constexpr const ImmutableString gl_MaxTessControlInputComponents(
+ "gl_MaxTessControlInputComponents");
+constexpr const ImmutableString gl_MaxTessControlOutputComponents(
+ "gl_MaxTessControlOutputComponents");
+constexpr const ImmutableString gl_MaxTessControlTextureImageUnits(
+ "gl_MaxTessControlTextureImageUnits");
+constexpr const ImmutableString gl_MaxTessControlTotalOutputComponents(
+ "gl_MaxTessControlTotalOutputComponents");
+constexpr const ImmutableString gl_MaxTessControlUniformComponents(
+ "gl_MaxTessControlUniformComponents");
+constexpr const ImmutableString gl_MaxTessEvaluationAtomicCounterBuffers(
+ "gl_MaxTessEvaluationAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxTessEvaluationAtomicCounters(
+ "gl_MaxTessEvaluationAtomicCounters");
+constexpr const ImmutableString gl_MaxTessEvaluationImageUniforms(
+ "gl_MaxTessEvaluationImageUniforms");
+constexpr const ImmutableString gl_MaxTessEvaluationInputComponents(
+ "gl_MaxTessEvaluationInputComponents");
+constexpr const ImmutableString gl_MaxTessEvaluationOutputComponents(
+ "gl_MaxTessEvaluationOutputComponents");
+constexpr const ImmutableString gl_MaxTessEvaluationTextureImageUnits(
+ "gl_MaxTessEvaluationTextureImageUnits");
+constexpr const ImmutableString gl_MaxTessEvaluationUniformComponents(
+ "gl_MaxTessEvaluationUniformComponents");
+constexpr const ImmutableString gl_MaxTessGenLevel("gl_MaxTessGenLevel");
+constexpr const ImmutableString gl_MaxTessPatchComponents("gl_MaxTessPatchComponents");
+constexpr const ImmutableString gl_MaxTextureImageUnits("gl_MaxTextureImageUnits");
+constexpr const ImmutableString gl_MaxVaryingVectors("gl_MaxVaryingVectors");
+constexpr const ImmutableString gl_MaxVertexAtomicCounterBuffers(
+ "gl_MaxVertexAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxVertexAtomicCounters("gl_MaxVertexAtomicCounters");
+constexpr const ImmutableString gl_MaxVertexAttribs("gl_MaxVertexAttribs");
+constexpr const ImmutableString gl_MaxVertexImageUniforms("gl_MaxVertexImageUniforms");
+constexpr const ImmutableString gl_MaxVertexOutputVectors("gl_MaxVertexOutputVectors");
+constexpr const ImmutableString gl_MaxVertexTextureImageUnits("gl_MaxVertexTextureImageUnits");
+constexpr const ImmutableString gl_MaxVertexUniformVectors("gl_MaxVertexUniformVectors");
+constexpr const ImmutableString gl_MinProgramTexelOffset("gl_MinProgramTexelOffset");
+constexpr const ImmutableString gl_NumSamples("gl_NumSamples");
+constexpr const ImmutableString gl_NumWorkGroups("gl_NumWorkGroups");
+constexpr const ImmutableString gl_PatchVerticesIn("gl_PatchVerticesIn");
+constexpr const ImmutableString gl_PerVertex("gl_PerVertex");
+constexpr const ImmutableString gl_PointCoord("gl_PointCoord");
+constexpr const ImmutableString gl_PointSize("gl_PointSize");
+constexpr const ImmutableString gl_Position("gl_Position");
+constexpr const ImmutableString gl_PrimitiveID("gl_PrimitiveID");
+constexpr const ImmutableString gl_PrimitiveIDIn("gl_PrimitiveIDIn");
+constexpr const ImmutableString gl_SampleID("gl_SampleID");
+constexpr const ImmutableString gl_SampleMask("gl_SampleMask");
+constexpr const ImmutableString gl_SampleMaskIn("gl_SampleMaskIn");
+constexpr const ImmutableString gl_SamplePosition("gl_SamplePosition");
+constexpr const ImmutableString gl_SecondaryFragColorEXT("gl_SecondaryFragColorEXT");
+constexpr const ImmutableString gl_SecondaryFragDataEXT("gl_SecondaryFragDataEXT");
+constexpr const ImmutableString gl_TessCoord("gl_TessCoord");
+constexpr const ImmutableString gl_TessLevelInner("gl_TessLevelInner");
+constexpr const ImmutableString gl_TessLevelOuter("gl_TessLevelOuter");
+constexpr const ImmutableString gl_VertexID("gl_VertexID");
+constexpr const ImmutableString gl_VertexIndex("gl_VertexIndex");
+constexpr const ImmutableString gl_ViewID_OVR("gl_ViewID_OVR");
+constexpr const ImmutableString gl_ViewportIndex("gl_ViewportIndex");
+constexpr const ImmutableString gl_WorkGroupID("gl_WorkGroupID");
+constexpr const ImmutableString gl_WorkGroupSize("gl_WorkGroupSize");
+constexpr const ImmutableString gl_in("gl_in");
+constexpr const ImmutableString gl_out("gl_out");
+constexpr const ImmutableString greaterThan("greaterThan");
+constexpr const ImmutableString greaterThanEqual("greaterThanEqual");
+constexpr const ImmutableString groupMemoryBarrier("groupMemoryBarrier");
+constexpr const ImmutableString imageAtomicAdd("imageAtomicAdd");
+constexpr const ImmutableString imageAtomicAddExt("imageAtomicAdd");
+constexpr const ImmutableString imageAtomicAnd("imageAtomicAnd");
+constexpr const ImmutableString imageAtomicAndExt("imageAtomicAnd");
+constexpr const ImmutableString imageAtomicCompSwap("imageAtomicCompSwap");
+constexpr const ImmutableString imageAtomicCompSwapExt("imageAtomicCompSwap");
+constexpr const ImmutableString imageAtomicExchange("imageAtomicExchange");
+constexpr const ImmutableString imageAtomicExchangeExt("imageAtomicExchange");
+constexpr const ImmutableString imageAtomicMax("imageAtomicMax");
+constexpr const ImmutableString imageAtomicMaxExt("imageAtomicMax");
+constexpr const ImmutableString imageAtomicMin("imageAtomicMin");
+constexpr const ImmutableString imageAtomicMinExt("imageAtomicMin");
+constexpr const ImmutableString imageAtomicOr("imageAtomicOr");
+constexpr const ImmutableString imageAtomicOrExt("imageAtomicOr");
+constexpr const ImmutableString imageAtomicXor("imageAtomicXor");
+constexpr const ImmutableString imageAtomicXorExt("imageAtomicXor");
+constexpr const ImmutableString imageLoad("imageLoad");
+constexpr const ImmutableString imageLoadExt("imageLoad");
+constexpr const ImmutableString imageSize("imageSize");
+constexpr const ImmutableString imageSizeExt("imageSize");
+constexpr const ImmutableString imageStore("imageStore");
+constexpr const ImmutableString imageStoreExt("imageStore");
+constexpr const ImmutableString imulExtended("imulExtended");
+constexpr const ImmutableString intBitsToFloat("intBitsToFloat");
+constexpr const ImmutableString interpolateAtCentroid("interpolateAtCentroid");
+constexpr const ImmutableString interpolateAtCentroidExt("interpolateAtCentroid");
+constexpr const ImmutableString interpolateAtOffset("interpolateAtOffset");
+constexpr const ImmutableString interpolateAtOffsetExt("interpolateAtOffset");
+constexpr const ImmutableString interpolateAtSample("interpolateAtSample");
+constexpr const ImmutableString interpolateAtSampleExt("interpolateAtSample");
+constexpr const ImmutableString inverse("inverse");
+constexpr const ImmutableString inversesqrt("inversesqrt");
+constexpr const ImmutableString isinf("isinf");
+constexpr const ImmutableString isnan("isnan");
+constexpr const ImmutableString ldexp("ldexp");
+constexpr const ImmutableString length("length");
+constexpr const ImmutableString lessThan("lessThan");
+constexpr const ImmutableString lessThanEqual("lessThanEqual");
+constexpr const ImmutableString log("log");
+constexpr const ImmutableString log2("log2");
+constexpr const ImmutableString matrixCompMult("matrixCompMult");
+constexpr const ImmutableString max("max");
+constexpr const ImmutableString memoryBarrier("memoryBarrier");
+constexpr const ImmutableString memoryBarrierAtomicCounter("memoryBarrierAtomicCounter");
+constexpr const ImmutableString memoryBarrierBuffer("memoryBarrierBuffer");
+constexpr const ImmutableString memoryBarrierImage("memoryBarrierImage");
+constexpr const ImmutableString memoryBarrierShared("memoryBarrierShared");
+constexpr const ImmutableString min("min");
+constexpr const ImmutableString mix("mix");
+constexpr const ImmutableString mod("mod");
+constexpr const ImmutableString modf("modf");
+constexpr const ImmutableString near("near");
+constexpr const ImmutableString normalize("normalize");
+constexpr const ImmutableString notEqual("notEqual");
+constexpr const ImmutableString notFunc("not");
+constexpr const ImmutableString outerProduct("outerProduct");
+constexpr const ImmutableString packHalf2x16("packHalf2x16");
+constexpr const ImmutableString packSnorm2x16("packSnorm2x16");
+constexpr const ImmutableString packSnorm4x8("packSnorm4x8");
+constexpr const ImmutableString packUnorm2x16("packUnorm2x16");
+constexpr const ImmutableString packUnorm4x8("packUnorm4x8");
+constexpr const ImmutableString pixelLocalLoadANGLE("pixelLocalLoadANGLE");
+constexpr const ImmutableString pixelLocalStoreANGLE("pixelLocalStoreANGLE");
+constexpr const ImmutableString pow("pow");
+constexpr const ImmutableString radians("radians");
+constexpr const ImmutableString reflect("reflect");
+constexpr const ImmutableString refract("refract");
+constexpr const ImmutableString rgb_2_yuv("rgb_2_yuv");
+constexpr const ImmutableString round("round");
+constexpr const ImmutableString roundEven("roundEven");
+constexpr const ImmutableString shadow2DEXT("shadow2DEXT");
+constexpr const ImmutableString shadow2DProjEXT("shadow2DProjEXT");
+constexpr const ImmutableString sign("sign");
+constexpr const ImmutableString sin("sin");
+constexpr const ImmutableString sinh("sinh");
+constexpr const ImmutableString smoothstep("smoothstep");
+constexpr const ImmutableString sqrt("sqrt");
+constexpr const ImmutableString step("step");
+constexpr const ImmutableString subpassLoad("subpassLoad");
+constexpr const ImmutableString tan("tan");
+constexpr const ImmutableString tanh("tanh");
+constexpr const ImmutableString texelFetch("texelFetch");
+constexpr const ImmutableString texelFetchExt("texelFetch");
+constexpr const ImmutableString texelFetchOffset("texelFetchOffset");
+constexpr const ImmutableString texture("texture");
+constexpr const ImmutableString texture2D("texture2D");
+constexpr const ImmutableString texture2DGradEXT("texture2DGradEXT");
+constexpr const ImmutableString texture2DLod("texture2DLod");
+constexpr const ImmutableString texture2DLodEXT("texture2DLodEXT");
+constexpr const ImmutableString texture2DProj("texture2DProj");
+constexpr const ImmutableString texture2DProjGradEXT("texture2DProjGradEXT");
+constexpr const ImmutableString texture2DProjLod("texture2DProjLod");
+constexpr const ImmutableString texture2DProjLodEXT("texture2DProjLodEXT");
+constexpr const ImmutableString texture2DRect("texture2DRect");
+constexpr const ImmutableString texture2DRectProj("texture2DRectProj");
+constexpr const ImmutableString texture3D("texture3D");
+constexpr const ImmutableString texture3DLod("texture3DLod");
+constexpr const ImmutableString texture3DProj("texture3DProj");
+constexpr const ImmutableString texture3DProjLod("texture3DProjLod");
+constexpr const ImmutableString textureCube("textureCube");
+constexpr const ImmutableString textureCubeGradEXT("textureCubeGradEXT");
+constexpr const ImmutableString textureCubeLod("textureCubeLod");
+constexpr const ImmutableString textureCubeLodEXT("textureCubeLodEXT");
+constexpr const ImmutableString textureExt("texture");
+constexpr const ImmutableString textureGather("textureGather");
+constexpr const ImmutableString textureGatherExt("textureGather");
+constexpr const ImmutableString textureGatherOffset("textureGatherOffset");
+constexpr const ImmutableString textureGatherOffsets("textureGatherOffsets");
+constexpr const ImmutableString textureGatherOffsetsExt("textureGatherOffsets");
+constexpr const ImmutableString textureGrad("textureGrad");
+constexpr const ImmutableString textureGradExt("textureGrad");
+constexpr const ImmutableString textureGradOffset("textureGradOffset");
+constexpr const ImmutableString textureLod("textureLod");
+constexpr const ImmutableString textureLodExt("textureLod");
+constexpr const ImmutableString textureLodOffset("textureLodOffset");
+constexpr const ImmutableString textureOffset("textureOffset");
+constexpr const ImmutableString textureProj("textureProj");
+constexpr const ImmutableString textureProjGrad("textureProjGrad");
+constexpr const ImmutableString textureProjGradOffset("textureProjGradOffset");
+constexpr const ImmutableString textureProjLod("textureProjLod");
+constexpr const ImmutableString textureProjLodOffset("textureProjLodOffset");
+constexpr const ImmutableString textureProjOffset("textureProjOffset");
+constexpr const ImmutableString textureSize("textureSize");
+constexpr const ImmutableString textureSizeExt("textureSize");
+constexpr const ImmutableString textureVideoWEBGL("textureVideoWEBGL");
+constexpr const ImmutableString transpose("transpose");
+constexpr const ImmutableString trunc("trunc");
+constexpr const ImmutableString uaddCarry("uaddCarry");
+constexpr const ImmutableString uintBitsToFloat("uintBitsToFloat");
+constexpr const ImmutableString umulExtended("umulExtended");
+constexpr const ImmutableString unpackHalf2x16("unpackHalf2x16");
+constexpr const ImmutableString unpackSnorm2x16("unpackSnorm2x16");
+constexpr const ImmutableString unpackSnorm4x8("unpackSnorm4x8");
+constexpr const ImmutableString unpackUnorm2x16("unpackUnorm2x16");
+constexpr const ImmutableString unpackUnorm4x8("unpackUnorm4x8");
+constexpr const ImmutableString usubBorrow("usubBorrow");
+constexpr const ImmutableString yuv_2_rgb("yuv_2_rgb");
+
+} // namespace BuiltInName
+
+// TODO(oetuaho): Would be nice to make this a class instead of a namespace so that we could friend
+// this from TVariable. Now symbol constructors taking an id have to be public even though they're
+// not supposed to be accessible from outside of here. http://anglebug.com/2390
+namespace BuiltInVariable
+{
+
+constexpr const unsigned int kArraySize4[1] = {4};
+
+constexpr const TVariable kangle_BaseInstance(
+ BuiltInId::angle_BaseInstance,
+ BuiltInName::angle_BaseInstance,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_base_vertex_base_instance_shader_builtin}},
+ StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>());
+constexpr const TVariable kangle_BaseVertex(
+ BuiltInId::angle_BaseVertex,
+ BuiltInName::angle_BaseVertex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_base_vertex_base_instance_shader_builtin}},
+ StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>());
+constexpr const TVariable kgl_BaseInstance(
+ BuiltInId::gl_BaseInstance,
+ BuiltInName::gl_BaseInstance,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_base_vertex_base_instance_shader_builtin}},
+ StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>());
+constexpr const TVariable kgl_BaseVertex(
+ BuiltInId::gl_BaseVertex,
+ BuiltInName::gl_BaseVertex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_base_vertex_base_instance_shader_builtin}},
+ StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>());
+constexpr const TVariable kgl_DrawID(BuiltInId::gl_DrawID,
+ BuiltInName::gl_DrawID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_multi_draw}},
+ StaticType::Get<EbtInt, EbpHigh, EvqDrawID, 1, 1>());
+constexpr const TVariable kgl_FragColor(BuiltInId::gl_FragColor,
+ BuiltInName::gl_FragColor,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqFragColor, 4, 1>());
+constexpr const TVariable kgl_FragCoord(BuiltInId::gl_FragCoord,
+ BuiltInName::gl_FragCoord,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqFragCoord, 4, 1>());
+constexpr const TVariable kgl_FragCoord300(
+ BuiltInId::gl_FragCoord300,
+ BuiltInName::gl_FragCoord,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpHigh, EvqFragCoord, 4, 1>());
+constexpr const TVariable kgl_FragDepth(BuiltInId::gl_FragDepth,
+ BuiltInName::gl_FragDepth,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpHigh, EvqFragDepth, 1, 1>());
+constexpr const TVariable kgl_FrontFacing(
+ BuiltInId::gl_FrontFacing,
+ BuiltInName::gl_FrontFacing,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqFrontFacing, 1, 1>());
+constexpr const TVariable kgl_GlobalInvocationID(
+ BuiltInId::gl_GlobalInvocationID,
+ BuiltInName::gl_GlobalInvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3, 1>());
+constexpr const TVariable kgl_HelperInvocation(
+ BuiltInId::gl_HelperInvocation,
+ BuiltInName::gl_HelperInvocation,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqHelperInvocation, 1, 1>());
+constexpr const TVariable kgl_InstanceID(BuiltInId::gl_InstanceID,
+ BuiltInName::gl_InstanceID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInstanceID, 1, 1>());
+constexpr const TVariable kgl_InstanceIndex(
+ BuiltInId::gl_InstanceIndex,
+ BuiltInName::gl_InstanceIndex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInstanceID, 1, 1>());
+constexpr const TVariable kgl_InvocationID(
+ BuiltInId::gl_InvocationID,
+ BuiltInName::gl_InvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>());
+constexpr const TVariable kgl_InvocationIDES3_2(
+ BuiltInId::gl_InvocationIDES3_2,
+ BuiltInName::gl_InvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>());
+constexpr const TVariable kgl_InvocationIDTCS(
+ BuiltInId::gl_InvocationIDTCS,
+ BuiltInName::gl_InvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>());
+constexpr const TVariable kgl_InvocationIDTCSES3_2(
+ BuiltInId::gl_InvocationIDTCSES3_2,
+ BuiltInName::gl_InvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>());
+constexpr const TVariable kgl_LastFragColor(
+ BuiltInId::gl_LastFragColor,
+ BuiltInName::gl_LastFragColor,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::NV_shader_framebuffer_fetch}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqLastFragColor, 4, 1>());
+constexpr const TVariable kgl_LastFragColorARM(
+ BuiltInId::gl_LastFragColorARM,
+ BuiltInName::gl_LastFragColorARM,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ARM_shader_framebuffer_fetch}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqLastFragColor, 4, 1>());
+constexpr const TVariable kgl_Layer(BuiltInId::gl_Layer,
+ BuiltInName::gl_Layer,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader,
+ TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqLayerIn, 1, 1>());
+constexpr const TVariable kgl_LayerES3_2(BuiltInId::gl_LayerES3_2,
+ BuiltInName::gl_Layer,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqLayerIn, 1, 1>());
+constexpr const TVariable kgl_LayerGS(BuiltInId::gl_LayerGS,
+ BuiltInName::gl_Layer,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader,
+ TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqLayerOut, 1, 1>());
+constexpr const TVariable kgl_LayerGSES3_2(BuiltInId::gl_LayerGSES3_2,
+ BuiltInName::gl_Layer,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqLayerOut, 1, 1>());
+constexpr const TVariable kgl_LayerVS(BuiltInId::gl_LayerVS,
+ BuiltInName::gl_Layer,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqLayerOut, 1, 1>());
+constexpr const TVariable kgl_LocalInvocationID(
+ BuiltInId::gl_LocalInvocationID,
+ BuiltInName::gl_LocalInvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationID, 3, 1>());
+constexpr const TVariable kgl_LocalInvocationIndex(
+ BuiltInId::gl_LocalInvocationIndex,
+ BuiltInName::gl_LocalInvocationIndex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1, 1>());
+constexpr const TVariable kgl_NumSamples(BuiltInId::gl_NumSamples,
+ BuiltInName::gl_NumSamples,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_sample_variables}},
+ StaticType::Get<EbtInt, EbpLow, EvqUniform, 1, 1>());
+constexpr const TVariable kgl_NumSamplesES3_2(BuiltInId::gl_NumSamplesES3_2,
+ BuiltInName::gl_NumSamples,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpLow, EvqUniform, 1, 1>());
+constexpr const TVariable kgl_NumWorkGroups(
+ BuiltInId::gl_NumWorkGroups,
+ BuiltInName::gl_NumWorkGroups,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqNumWorkGroups, 3, 1>());
+constexpr const TVariable kgl_PatchVerticesInTCS(
+ BuiltInId::gl_PatchVerticesInTCS,
+ BuiltInName::gl_PatchVerticesIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPatchVerticesIn, 1, 1>());
+constexpr const TVariable kgl_PatchVerticesInTCSES3_2(
+ BuiltInId::gl_PatchVerticesInTCSES3_2,
+ BuiltInName::gl_PatchVerticesIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPatchVerticesIn, 1, 1>());
+constexpr const TVariable kgl_PatchVerticesInTES(
+ BuiltInId::gl_PatchVerticesInTES,
+ BuiltInName::gl_PatchVerticesIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPatchVerticesIn, 1, 1>());
+constexpr const TVariable kgl_PatchVerticesInTESES3_2(
+ BuiltInId::gl_PatchVerticesInTESES3_2,
+ BuiltInName::gl_PatchVerticesIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPatchVerticesIn, 1, 1>());
+constexpr const TVariable kgl_PointCoord(
+ BuiltInId::gl_PointCoord,
+ BuiltInName::gl_PointCoord,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqPointCoord, 2, 1>());
+constexpr const TVariable kgl_PointSize(BuiltInId::gl_PointSize,
+ BuiltInName::gl_PointSize,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqPointSize, 1, 1>());
+constexpr const TVariable kgl_PointSize300(
+ BuiltInId::gl_PointSize300,
+ BuiltInName::gl_PointSize,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpHigh, EvqPointSize, 1, 1>());
+constexpr const TVariable kgl_Position(BuiltInId::gl_Position,
+ BuiltInName::gl_Position,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpHigh, EvqPosition, 4, 1>());
+constexpr const TVariable kgl_PrimitiveID(
+ BuiltInId::gl_PrimitiveID,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDES3_2(
+ BuiltInId::gl_PrimitiveIDES3_2,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDGS(
+ BuiltInId::gl_PrimitiveIDGS,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDGSES3_2(
+ BuiltInId::gl_PrimitiveIDGSES3_2,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDIn(
+ BuiltInId::gl_PrimitiveIDIn,
+ BuiltInName::gl_PrimitiveIDIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveIDIn, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDInES3_2(
+ BuiltInId::gl_PrimitiveIDInES3_2,
+ BuiltInName::gl_PrimitiveIDIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveIDIn, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDTCS(
+ BuiltInId::gl_PrimitiveIDTCS,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDTCSES3_2(
+ BuiltInId::gl_PrimitiveIDTCSES3_2,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDTES(
+ BuiltInId::gl_PrimitiveIDTES,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDTESES3_2(
+ BuiltInId::gl_PrimitiveIDTESES3_2,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_SampleID(BuiltInId::gl_SampleID,
+ BuiltInName::gl_SampleID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_sample_variables}},
+ StaticType::Get<EbtInt, EbpLow, EvqSampleID, 1, 1>());
+constexpr const TVariable kgl_SampleIDES3_2(BuiltInId::gl_SampleIDES3_2,
+ BuiltInName::gl_SampleID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpLow, EvqSampleID, 1, 1>());
+constexpr const TVariable kgl_SamplePosition(
+ BuiltInId::gl_SamplePosition,
+ BuiltInName::gl_SamplePosition,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::OES_sample_variables}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqSamplePosition, 2, 1>());
+constexpr const TVariable kgl_SamplePositionES3_2(
+ BuiltInId::gl_SamplePositionES3_2,
+ BuiltInName::gl_SamplePosition,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqSamplePosition, 2, 1>());
+constexpr const TVariable kgl_SecondaryFragColorEXT(
+ BuiltInId::gl_SecondaryFragColorEXT,
+ BuiltInName::gl_SecondaryFragColorEXT,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_blend_func_extended}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4, 1>());
+constexpr const TVariable kgl_TessCoord(BuiltInId::gl_TessCoord,
+ BuiltInName::gl_TessCoord,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpHigh, EvqTessCoord, 3, 1>());
+constexpr const TVariable kgl_VertexID(BuiltInId::gl_VertexID,
+ BuiltInName::gl_VertexID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqVertexID, 1, 1>());
+constexpr const TVariable kgl_VertexIndex(BuiltInId::gl_VertexIndex,
+ BuiltInName::gl_VertexIndex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqVertexID, 1, 1>());
+constexpr const TVariable kgl_ViewID_OVR(BuiltInId::gl_ViewID_OVR,
+ BuiltInName::gl_ViewID_OVR,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::OVR_multiview}},
+ StaticType::Get<EbtUInt, EbpHigh, EvqViewIDOVR, 1, 1>());
+constexpr const TVariable kgl_ViewportIndex(
+ BuiltInId::gl_ViewportIndex,
+ BuiltInName::gl_ViewportIndex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqViewportIndex, 1, 1>());
+constexpr const TVariable kgl_WorkGroupID(
+ BuiltInId::gl_WorkGroupID,
+ BuiltInName::gl_WorkGroupID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupID, 3, 1>());
+constexpr const TVariable kgl_WorkGroupSize(
+ BuiltInId::gl_WorkGroupSize,
+ BuiltInName::gl_WorkGroupSize,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupSize, 3, 1>());
+constexpr const TVariable kpt00B(BuiltInId::pt00B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00D(BuiltInId::pt00D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00E(BuiltInId::pt00E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00F(BuiltInId::pt00F,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00G(
+ BuiltInId::pt00G,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtAtomicCounter, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00H(
+ BuiltInId::pt00H,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtYuvCscStandardEXT, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00I(BuiltInId::pt00I,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00J(BuiltInId::pt00J,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00K(BuiltInId::pt00K,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00L(
+ BuiltInId::pt00L,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00M(
+ BuiltInId::pt00M,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerExternalOES, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00N(
+ BuiltInId::pt00N,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerExternal2DY2YEXT, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00O(
+ BuiltInId::pt00O,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DRect, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00P(BuiltInId::pt00P,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00Q(
+ BuiltInId::pt00Q,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00R(BuiltInId::pt00R,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISampler2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00S(BuiltInId::pt00S,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISampler3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00T(BuiltInId::pt00T,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISamplerCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00U(
+ BuiltInId::pt00U,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISampler2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00V(BuiltInId::pt00V,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISampler2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00W(
+ BuiltInId::pt00W,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISampler2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00X(BuiltInId::pt00X,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSampler2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00Y(BuiltInId::pt00Y,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSampler3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00Z(BuiltInId::pt00Z,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSamplerCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00a(
+ BuiltInId::pt00a,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSampler2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00b(BuiltInId::pt00b,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSampler2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00c(
+ BuiltInId::pt00c,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSampler2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00d(
+ BuiltInId::pt00d,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DShadow, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00e(
+ BuiltInId::pt00e,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerCubeShadow, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00f(
+ BuiltInId::pt00f,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DArrayShadow, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00j(
+ BuiltInId::pt00j,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00k(
+ BuiltInId::pt00k,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00l(
+ BuiltInId::pt00l,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerCubeArrayShadow, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00r(
+ BuiltInId::pt00r,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISamplerBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00s(
+ BuiltInId::pt00s,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISamplerCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00w(
+ BuiltInId::pt00w,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSamplerBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00x(
+ BuiltInId::pt00x,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSamplerCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00y(
+ BuiltInId::pt00y,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerVideoWEBGL, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00z(BuiltInId::pt00z,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01A(BuiltInId::pt01A,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01B(BuiltInId::pt01B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01C(BuiltInId::pt01C,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImageCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01D(BuiltInId::pt01D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage1D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01E(BuiltInId::pt01E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage1DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01F(BuiltInId::pt01F,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01G(
+ BuiltInId::pt01G,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01H(
+ BuiltInId::pt01H,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImageCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01I(BuiltInId::pt01I,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImageRect, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01J(BuiltInId::pt01J,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImageBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01K(BuiltInId::pt01K,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01L(BuiltInId::pt01L,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01M(
+ BuiltInId::pt01M,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01N(BuiltInId::pt01N,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImageCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01O(BuiltInId::pt01O,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage1D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01P(
+ BuiltInId::pt01P,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage1DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01Q(BuiltInId::pt01Q,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01R(
+ BuiltInId::pt01R,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01S(
+ BuiltInId::pt01S,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImageCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01T(BuiltInId::pt01T,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImageRect, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01U(BuiltInId::pt01U,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImageBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01V(BuiltInId::pt01V,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01W(BuiltInId::pt01W,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01X(
+ BuiltInId::pt01X,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01Y(BuiltInId::pt01Y,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImageCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01Z(BuiltInId::pt01Z,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage1D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01a(
+ BuiltInId::pt01a,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage1DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01b(BuiltInId::pt01b,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01c(
+ BuiltInId::pt01c,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01d(
+ BuiltInId::pt01d,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImageCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01e(BuiltInId::pt01e,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImageRect, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01f(BuiltInId::pt01f,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImageBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01g(
+ BuiltInId::pt01g,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtPixelLocalANGLE, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01h(
+ BuiltInId::pt01h,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIPixelLocalANGLE, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01i(
+ BuiltInId::pt01i,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUPixelLocalANGLE, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01j(BuiltInId::pt01j,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSubpassInput, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01k(
+ BuiltInId::pt01k,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISubpassInput, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01l(
+ BuiltInId::pt01l,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSubpassInput, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01m(
+ BuiltInId::pt01m,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSubpassInputMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01n(
+ BuiltInId::pt01n,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISubpassInputMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01o(
+ BuiltInId::pt01o,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSubpassInputMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt10B(BuiltInId::pt10B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kpt10D(BuiltInId::pt10D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kpt10Dx4(
+ BuiltInId::pt10Dx4,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::GetArray<EbtInt, EbpUndefined, EvqGlobal, 2, 1, kArraySize4, 1>());
+constexpr const TVariable kpt10E(BuiltInId::pt10E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kpt10F(BuiltInId::pt10F,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kpt20B(BuiltInId::pt20B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kpt20D(BuiltInId::pt20D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kpt20E(BuiltInId::pt20E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kpt20F(BuiltInId::pt20F,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kpt30B(BuiltInId::pt30B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kpt30D(BuiltInId::pt30D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kpt30E(BuiltInId::pt30E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kpt30F(BuiltInId::pt30F,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kpt50B(BuiltInId::pt50B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>());
+constexpr const TVariable kpt60B(BuiltInId::pt60B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>());
+constexpr const TVariable kpt70B(BuiltInId::pt70B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>());
+constexpr const TVariable kpt90B(BuiltInId::pt90B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>());
+constexpr const TVariable kptA0B(BuiltInId::ptA0B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>());
+constexpr const TVariable kptB0B(BuiltInId::ptB0B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>());
+constexpr const TVariable kptD0B(BuiltInId::ptD0B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>());
+constexpr const TVariable kptE0B(BuiltInId::ptE0B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>());
+constexpr const TVariable kptF0B(BuiltInId::ptF0B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>());
+constexpr const TVariable kpt_io_00D(BuiltInId::pt_io_00D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqParamInOut, 1, 1>());
+constexpr const TVariable kpt_io_00E(BuiltInId::pt_io_00E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqParamInOut, 1, 1>());
+constexpr const TVariable kpt_o_00B(BuiltInId::pt_o_00B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqParamOut, 1, 1>());
+constexpr const TVariable kpt_o_00D(BuiltInId::pt_o_00D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqParamOut, 1, 1>());
+constexpr const TVariable kpt_o_00E(BuiltInId::pt_o_00E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqParamOut, 1, 1>());
+constexpr const TVariable kpt_o_10B(BuiltInId::pt_o_10B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqParamOut, 2, 1>());
+constexpr const TVariable kpt_o_10D(BuiltInId::pt_o_10D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqParamOut, 2, 1>());
+constexpr const TVariable kpt_o_10E(BuiltInId::pt_o_10E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqParamOut, 2, 1>());
+constexpr const TVariable kpt_o_20B(BuiltInId::pt_o_20B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqParamOut, 3, 1>());
+constexpr const TVariable kpt_o_20D(BuiltInId::pt_o_20D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqParamOut, 3, 1>());
+constexpr const TVariable kpt_o_20E(BuiltInId::pt_o_20E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqParamOut, 3, 1>());
+constexpr const TVariable kpt_o_30B(BuiltInId::pt_o_30B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqParamOut, 4, 1>());
+constexpr const TVariable kpt_o_30D(BuiltInId::pt_o_30D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqParamOut, 4, 1>());
+constexpr const TVariable kpt_o_30E(BuiltInId::pt_o_30E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqParamOut, 4, 1>());
+
+const TVariable *angle_BaseInstance()
+{
+ return &kangle_BaseInstance;
+}
+
+const TVariable *angle_BaseVertex()
+{
+ return &kangle_BaseVertex;
+}
+
+const TVariable *gl_BaseInstance()
+{
+ return &kgl_BaseInstance;
+}
+
+const TVariable *gl_BaseVertex()
+{
+ return &kgl_BaseVertex;
+}
+
+const TVariable *gl_DrawID()
+{
+ return &kgl_DrawID;
+}
+
+const TVariable *gl_FragColor()
+{
+ return &kgl_FragColor;
+}
+
+const TVariable *gl_FragCoord()
+{
+ return &kgl_FragCoord;
+}
+
+const TVariable *gl_FragCoord300()
+{
+ return &kgl_FragCoord300;
+}
+
+const TVariable *gl_FragDepth()
+{
+ return &kgl_FragDepth;
+}
+
+const TVariable *gl_FrontFacing()
+{
+ return &kgl_FrontFacing;
+}
+
+const TVariable *gl_GlobalInvocationID()
+{
+ return &kgl_GlobalInvocationID;
+}
+
+const TVariable *gl_HelperInvocation()
+{
+ return &kgl_HelperInvocation;
+}
+
+const TVariable *gl_InstanceID()
+{
+ return &kgl_InstanceID;
+}
+
+const TVariable *gl_InstanceIndex()
+{
+ return &kgl_InstanceIndex;
+}
+
+const TVariable *gl_InvocationID()
+{
+ return &kgl_InvocationID;
+}
+
+const TVariable *gl_InvocationIDES3_2()
+{
+ return &kgl_InvocationIDES3_2;
+}
+
+const TVariable *gl_InvocationIDTCS()
+{
+ return &kgl_InvocationIDTCS;
+}
+
+const TVariable *gl_InvocationIDTCSES3_2()
+{
+ return &kgl_InvocationIDTCSES3_2;
+}
+
+const TVariable *gl_LastFragColor()
+{
+ return &kgl_LastFragColor;
+}
+
+const TVariable *gl_LastFragColorARM()
+{
+ return &kgl_LastFragColorARM;
+}
+
+const TVariable *gl_Layer()
+{
+ return &kgl_Layer;
+}
+
+const TVariable *gl_LayerES3_2()
+{
+ return &kgl_LayerES3_2;
+}
+
+const TVariable *gl_LayerGS()
+{
+ return &kgl_LayerGS;
+}
+
+const TVariable *gl_LayerGSES3_2()
+{
+ return &kgl_LayerGSES3_2;
+}
+
+const TVariable *gl_LayerVS()
+{
+ return &kgl_LayerVS;
+}
+
+const TVariable *gl_LocalInvocationID()
+{
+ return &kgl_LocalInvocationID;
+}
+
+const TVariable *gl_LocalInvocationIndex()
+{
+ return &kgl_LocalInvocationIndex;
+}
+
+const TVariable *gl_NumSamples()
+{
+ return &kgl_NumSamples;
+}
+
+const TVariable *gl_NumSamplesES3_2()
+{
+ return &kgl_NumSamplesES3_2;
+}
+
+const TVariable *gl_NumWorkGroups()
+{
+ return &kgl_NumWorkGroups;
+}
+
+const TVariable *gl_PatchVerticesInTCS()
+{
+ return &kgl_PatchVerticesInTCS;
+}
+
+const TVariable *gl_PatchVerticesInTCSES3_2()
+{
+ return &kgl_PatchVerticesInTCSES3_2;
+}
+
+const TVariable *gl_PatchVerticesInTES()
+{
+ return &kgl_PatchVerticesInTES;
+}
+
+const TVariable *gl_PatchVerticesInTESES3_2()
+{
+ return &kgl_PatchVerticesInTESES3_2;
+}
+
+const TVariable *gl_PointCoord()
+{
+ return &kgl_PointCoord;
+}
+
+const TVariable *gl_PointSize()
+{
+ return &kgl_PointSize;
+}
+
+const TVariable *gl_PointSize300()
+{
+ return &kgl_PointSize300;
+}
+
+const TVariable *gl_Position()
+{
+ return &kgl_Position;
+}
+
+const TVariable *gl_PrimitiveID()
+{
+ return &kgl_PrimitiveID;
+}
+
+const TVariable *gl_PrimitiveIDES3_2()
+{
+ return &kgl_PrimitiveIDES3_2;
+}
+
+const TVariable *gl_PrimitiveIDGS()
+{
+ return &kgl_PrimitiveIDGS;
+}
+
+const TVariable *gl_PrimitiveIDGSES3_2()
+{
+ return &kgl_PrimitiveIDGSES3_2;
+}
+
+const TVariable *gl_PrimitiveIDIn()
+{
+ return &kgl_PrimitiveIDIn;
+}
+
+const TVariable *gl_PrimitiveIDInES3_2()
+{
+ return &kgl_PrimitiveIDInES3_2;
+}
+
+const TVariable *gl_PrimitiveIDTCS()
+{
+ return &kgl_PrimitiveIDTCS;
+}
+
+const TVariable *gl_PrimitiveIDTCSES3_2()
+{
+ return &kgl_PrimitiveIDTCSES3_2;
+}
+
+const TVariable *gl_PrimitiveIDTES()
+{
+ return &kgl_PrimitiveIDTES;
+}
+
+const TVariable *gl_PrimitiveIDTESES3_2()
+{
+ return &kgl_PrimitiveIDTESES3_2;
+}
+
+const TVariable *gl_SampleID()
+{
+ return &kgl_SampleID;
+}
+
+const TVariable *gl_SampleIDES3_2()
+{
+ return &kgl_SampleIDES3_2;
+}
+
+const TVariable *gl_SamplePosition()
+{
+ return &kgl_SamplePosition;
+}
+
+const TVariable *gl_SamplePositionES3_2()
+{
+ return &kgl_SamplePositionES3_2;
+}
+
+const TVariable *gl_SecondaryFragColorEXT()
+{
+ return &kgl_SecondaryFragColorEXT;
+}
+
+const TVariable *gl_TessCoord()
+{
+ return &kgl_TessCoord;
+}
+
+const TVariable *gl_VertexID()
+{
+ return &kgl_VertexID;
+}
+
+const TVariable *gl_VertexIndex()
+{
+ return &kgl_VertexIndex;
+}
+
+const TVariable *gl_ViewID_OVR()
+{
+ return &kgl_ViewID_OVR;
+}
+
+const TVariable *gl_ViewportIndex()
+{
+ return &kgl_ViewportIndex;
+}
+
+const TVariable *gl_WorkGroupID()
+{
+ return &kgl_WorkGroupID;
+}
+
+const TVariable *gl_WorkGroupSize()
+{
+ return &kgl_WorkGroupSize;
+}
+
+} // namespace BuiltInVariable
+
+namespace BuiltInParameters
+{
+
+constexpr const TVariable **empty = nullptr;
+constexpr const TVariable *p00B00B00B[3] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00B00B00F[3] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt00F};
+constexpr const TVariable *p00B00B10B[3] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt10B};
+constexpr const TVariable *p00B00B20B[3] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00B00B30B[3] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p00B00D[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00B10B[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt10B};
+constexpr const TVariable *p00B20B[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00B30B[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt30B};
+constexpr const TVariable *p00B_o_00B[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt_o_00B};
+constexpr const TVariable *p00B_o_00D[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt_o_00D};
+constexpr const TVariable *p00D00D00D00D[4] = {&BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00D00D00F[3] = {&BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00F};
+constexpr const TVariable *p00D00D_o_00D_o_00D[4] = {
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D, &BuiltInVariable::kpt_o_00D,
+ &BuiltInVariable::kpt_o_00D};
+constexpr const TVariable *p00E00D00D[3] = {&BuiltInVariable::kpt00E, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00E00E00D00D[4] = {&BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00E00E00E[3] = {&BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00E};
+constexpr const TVariable *p00E00E00F[3] = {&BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00F};
+constexpr const TVariable *p00E00E_o_00E_o_00E[4] = {
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E, &BuiltInVariable::kpt_o_00E,
+ &BuiltInVariable::kpt_o_00E};
+constexpr const TVariable *p00F00F00F[3] = {&BuiltInVariable::kpt00F, &BuiltInVariable::kpt00F,
+ &BuiltInVariable::kpt00F};
+constexpr const TVariable *p00G[1] = {&BuiltInVariable::kpt00G};
+constexpr const TVariable *p00I00D[2] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00I10B00B10D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I10B00D[3] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00I10B10B10B10D[5] = {
+ &BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I10B10D00B[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00I10B10D00D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00I10B10Dx400D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00I10D00D10D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I20B00B10D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00I, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I20B10D00B[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00I30B00B10D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I30B10B10B10D[5] = {
+ &BuiltInVariable::kpt00I, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I30B10D00B[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00J00D[2] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00J20B00B20D[4] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00J20B20B20B20D[5] = {
+ &BuiltInVariable::kpt00J, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00J20B20D00B[4] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00J20D00D20D[4] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00J30B00B20D[4] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00J30B20B20B20D[5] = {
+ &BuiltInVariable::kpt00J, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00J30B20D00B[4] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00K00D[2] = {&BuiltInVariable::kpt00K, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00K20B00B[3] = {&BuiltInVariable::kpt00K, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00K20B00D[3] = {&BuiltInVariable::kpt00K, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00K20B20B20B[4] = {&BuiltInVariable::kpt00K, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00L00D[2] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00L20B00B10D[4] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00L20B00D[3] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00L20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00L20B10D00B[4] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00L20B10D00D[4] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00L20B10Dx400D[4] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00L20D00D10D[4] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00M00D[2] = {&BuiltInVariable::kpt00M, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00M10B00B[3] = {&BuiltInVariable::kpt00M, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00M10D00D[3] = {&BuiltInVariable::kpt00M, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00M20B00B[3] = {&BuiltInVariable::kpt00M, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00M30B00B[3] = {&BuiltInVariable::kpt00M, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00N00D[2] = {&BuiltInVariable::kpt00N, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00N10B00B[3] = {&BuiltInVariable::kpt00N, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00N10D00D[3] = {&BuiltInVariable::kpt00N, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00N20B00B[3] = {&BuiltInVariable::kpt00N, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00N30B00B[3] = {&BuiltInVariable::kpt00N, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00O10B[2] = {&BuiltInVariable::kpt00O, &BuiltInVariable::kpt10B};
+constexpr const TVariable *p00O20B[2] = {&BuiltInVariable::kpt00O, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00O30B[2] = {&BuiltInVariable::kpt00O, &BuiltInVariable::kpt30B};
+constexpr const TVariable *p00P10D00D[3] = {&BuiltInVariable::kpt00P, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00Q20D00D[3] = {&BuiltInVariable::kpt00Q, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00R00D[2] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00R10B00B10D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R10B00D[3] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00R10B10B10B10D[5] = {
+ &BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R10B10D00B[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00R10B10D00D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00R10B10Dx400D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00R10D00D10D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R20B00B10D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00R, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R20B10D00B[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00R30B00B10D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R30B10B10B10D[5] = {
+ &BuiltInVariable::kpt00R, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R30B10D00B[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00S00D[2] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00S20B00B20D[4] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00S20B20B20B20D[5] = {
+ &BuiltInVariable::kpt00S, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00S20B20D00B[4] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00S20D00D20D[4] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00S30B00B20D[4] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00S30B20B20B20D[5] = {
+ &BuiltInVariable::kpt00S, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00S30B20D00B[4] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00T00D[2] = {&BuiltInVariable::kpt00T, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00T20B00B[3] = {&BuiltInVariable::kpt00T, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00T20B00D[3] = {&BuiltInVariable::kpt00T, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00T20B20B20B[4] = {&BuiltInVariable::kpt00T, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00U00D[2] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00U20B00B10D[4] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00U20B00D[3] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00U20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00U20B10D00B[4] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00U20B10D00D[4] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00U20B10Dx400D[4] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00U20D00D10D[4] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00V10D00D[3] = {&BuiltInVariable::kpt00V, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00W20D00D[3] = {&BuiltInVariable::kpt00W, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00X00D[2] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00X10B00B10D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X10B00D[3] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00X10B10B10B10D[5] = {
+ &BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X10B10D00B[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00X10B10D00D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00X10B10Dx400D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00X10D00D10D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X20B00B10D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00X, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X20B10D00B[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00X30B00B10D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X30B10B10B10D[5] = {
+ &BuiltInVariable::kpt00X, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X30B10D00B[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00Y00D[2] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00Y20B00B20D[4] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00Y20B20B20B20D[5] = {
+ &BuiltInVariable::kpt00Y, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00Y20B20D00B[4] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00Y20D00D20D[4] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00Y30B00B20D[4] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00Y30B20B20B20D[5] = {
+ &BuiltInVariable::kpt00Y, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00Y30B20D00B[4] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00Z00D[2] = {&BuiltInVariable::kpt00Z, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00Z20B00B[3] = {&BuiltInVariable::kpt00Z, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00Z20B00D[3] = {&BuiltInVariable::kpt00Z, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00Z20B20B20B[4] = {&BuiltInVariable::kpt00Z, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00a00D[2] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00a20B00B10D[4] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00a20B00D[3] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00a20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00a20B10D00B[4] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00a20B10D00D[4] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00a20B10Dx400D[4] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00a20D00D10D[4] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00b10D00D[3] = {&BuiltInVariable::kpt00b, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00c20D00D[3] = {&BuiltInVariable::kpt00c, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00d00D[2] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00d10B00B10Dx4[4] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt10Dx4};
+constexpr const TVariable *p00d20B00B10D[4] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00d20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00d, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00d20B10D00B[4] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00d30B00B10D[4] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00d30B10B10B10D[5] = {
+ &BuiltInVariable::kpt00d, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00d30B10D00B[4] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00e00D[2] = {&BuiltInVariable::kpt00e, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00e20B00B[3] = {&BuiltInVariable::kpt00e, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00e30B00B[3] = {&BuiltInVariable::kpt00e, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00e30B20B20B[4] = {&BuiltInVariable::kpt00e, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00f00D[2] = {&BuiltInVariable::kpt00f, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00f20B00B10Dx4[4] = {&BuiltInVariable::kpt00f, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt10Dx4};
+constexpr const TVariable *p00f30B10B10B10D[5] = {
+ &BuiltInVariable::kpt00f, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00j00D[2] = {&BuiltInVariable::kpt00j, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00k00D[2] = {&BuiltInVariable::kpt00k, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00k30B00B[3] = {&BuiltInVariable::kpt00k, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00k30B00D[3] = {&BuiltInVariable::kpt00k, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00k30B20B20B[4] = {&BuiltInVariable::kpt00k, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00l00D[2] = {&BuiltInVariable::kpt00l, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00l30B00B[3] = {&BuiltInVariable::kpt00l, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00r00D[2] = {&BuiltInVariable::kpt00r, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00s00D[2] = {&BuiltInVariable::kpt00s, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00s30B00B[3] = {&BuiltInVariable::kpt00s, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00s30B00D[3] = {&BuiltInVariable::kpt00s, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00s30B20B20B[4] = {&BuiltInVariable::kpt00s, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00w00D[2] = {&BuiltInVariable::kpt00w, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00x00D[2] = {&BuiltInVariable::kpt00x, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00x30B00B[3] = {&BuiltInVariable::kpt00x, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00x30B00D[3] = {&BuiltInVariable::kpt00x, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00x30B20B20B[4] = {&BuiltInVariable::kpt00x, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00y10B[2] = {&BuiltInVariable::kpt00y, &BuiltInVariable::kpt10B};
+constexpr const TVariable *p00z10D00B[3] = {&BuiltInVariable::kpt00z, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00z10D00D00D[4] = {&BuiltInVariable::kpt00z, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00z10D00E00E[4] = {&BuiltInVariable::kpt00z, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p00z10D30B[3] = {&BuiltInVariable::kpt00z, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01A20D00B[3] = {&BuiltInVariable::kpt01A, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01A20D00D00D[4] = {&BuiltInVariable::kpt01A, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01A20D00E00E[4] = {&BuiltInVariable::kpt01A, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01A20D30B[3] = {&BuiltInVariable::kpt01A, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01B20D00B[3] = {&BuiltInVariable::kpt01B, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01B20D00D00D[4] = {&BuiltInVariable::kpt01B, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01B20D00E00E[4] = {&BuiltInVariable::kpt01B, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01B20D30B[3] = {&BuiltInVariable::kpt01B, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01C20D00B[3] = {&BuiltInVariable::kpt01C, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01C20D00D00D[4] = {&BuiltInVariable::kpt01C, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01C20D00E00E[4] = {&BuiltInVariable::kpt01C, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01C20D30B[3] = {&BuiltInVariable::kpt01C, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01D00D00B[3] = {&BuiltInVariable::kpt01D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01D00D00D00D[4] = {&BuiltInVariable::kpt01D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01D00D00E00E[4] = {&BuiltInVariable::kpt01D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01E10D00B[3] = {&BuiltInVariable::kpt01E, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01E10D00D00D[4] = {&BuiltInVariable::kpt01E, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01E10D00E00E[4] = {&BuiltInVariable::kpt01E, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01F10D00D00B[4] = {&BuiltInVariable::kpt01F, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01F10D00D00D00D[5] = {
+ &BuiltInVariable::kpt01F, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01F10D00D00E00E[5] = {
+ &BuiltInVariable::kpt01F, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01G20D00D00B[4] = {&BuiltInVariable::kpt01G, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01G20D00D00D00D[5] = {
+ &BuiltInVariable::kpt01G, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01G20D00D00E00E[5] = {
+ &BuiltInVariable::kpt01G, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01H20D00B[3] = {&BuiltInVariable::kpt01H, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01H20D00D00D[4] = {&BuiltInVariable::kpt01H, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01H20D00E00E[4] = {&BuiltInVariable::kpt01H, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01H20D30B[3] = {&BuiltInVariable::kpt01H, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01I10D00B[3] = {&BuiltInVariable::kpt01I, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01I10D00D00D[4] = {&BuiltInVariable::kpt01I, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01I10D00E00E[4] = {&BuiltInVariable::kpt01I, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01J00D00B[3] = {&BuiltInVariable::kpt01J, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01J00D00D00D[4] = {&BuiltInVariable::kpt01J, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01J00D00E00E[4] = {&BuiltInVariable::kpt01J, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01J00D30B[3] = {&BuiltInVariable::kpt01J, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01K10D00B[3] = {&BuiltInVariable::kpt01K, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01K10D00D00D[4] = {&BuiltInVariable::kpt01K, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01K10D00E00E[4] = {&BuiltInVariable::kpt01K, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01K10D30D[3] = {&BuiltInVariable::kpt01K, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01L20D00B[3] = {&BuiltInVariable::kpt01L, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01L20D00D00D[4] = {&BuiltInVariable::kpt01L, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01L20D00E00E[4] = {&BuiltInVariable::kpt01L, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01L20D30D[3] = {&BuiltInVariable::kpt01L, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01M20D00B[3] = {&BuiltInVariable::kpt01M, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01M20D00D00D[4] = {&BuiltInVariable::kpt01M, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01M20D00E00E[4] = {&BuiltInVariable::kpt01M, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01M20D30D[3] = {&BuiltInVariable::kpt01M, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01N20D00B[3] = {&BuiltInVariable::kpt01N, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01N20D00D00D[4] = {&BuiltInVariable::kpt01N, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01N20D00E00E[4] = {&BuiltInVariable::kpt01N, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01N20D30D[3] = {&BuiltInVariable::kpt01N, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01O00D00B[3] = {&BuiltInVariable::kpt01O, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01O00D00D00D[4] = {&BuiltInVariable::kpt01O, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01O00D00E00E[4] = {&BuiltInVariable::kpt01O, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01P10D00B[3] = {&BuiltInVariable::kpt01P, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01P10D00D00D[4] = {&BuiltInVariable::kpt01P, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01P10D00E00E[4] = {&BuiltInVariable::kpt01P, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01Q10D00D00B[4] = {&BuiltInVariable::kpt01Q, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01Q10D00D00D00D[5] = {
+ &BuiltInVariable::kpt01Q, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01Q10D00D00E00E[5] = {
+ &BuiltInVariable::kpt01Q, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01R20D00D00B[4] = {&BuiltInVariable::kpt01R, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01R20D00D00D00D[5] = {
+ &BuiltInVariable::kpt01R, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01R20D00D00E00E[5] = {
+ &BuiltInVariable::kpt01R, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01S20D00B[3] = {&BuiltInVariable::kpt01S, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01S20D00D00D[4] = {&BuiltInVariable::kpt01S, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01S20D00E00E[4] = {&BuiltInVariable::kpt01S, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01S20D30D[3] = {&BuiltInVariable::kpt01S, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01T10D00B[3] = {&BuiltInVariable::kpt01T, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01T10D00D00D[4] = {&BuiltInVariable::kpt01T, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01T10D00E00E[4] = {&BuiltInVariable::kpt01T, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01U00D00B[3] = {&BuiltInVariable::kpt01U, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01U00D00D00D[4] = {&BuiltInVariable::kpt01U, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01U00D00E00E[4] = {&BuiltInVariable::kpt01U, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01U00D30D[3] = {&BuiltInVariable::kpt01U, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01V10D00B[3] = {&BuiltInVariable::kpt01V, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01V10D00D00D[4] = {&BuiltInVariable::kpt01V, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01V10D00E00E[4] = {&BuiltInVariable::kpt01V, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01V10D30E[3] = {&BuiltInVariable::kpt01V, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01W20D00B[3] = {&BuiltInVariable::kpt01W, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01W20D00D00D[4] = {&BuiltInVariable::kpt01W, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01W20D00E00E[4] = {&BuiltInVariable::kpt01W, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01W20D30E[3] = {&BuiltInVariable::kpt01W, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01X20D00B[3] = {&BuiltInVariable::kpt01X, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01X20D00D00D[4] = {&BuiltInVariable::kpt01X, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01X20D00E00E[4] = {&BuiltInVariable::kpt01X, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01X20D30E[3] = {&BuiltInVariable::kpt01X, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01Y20D00B[3] = {&BuiltInVariable::kpt01Y, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01Y20D00D00D[4] = {&BuiltInVariable::kpt01Y, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01Y20D00E00E[4] = {&BuiltInVariable::kpt01Y, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01Y20D30E[3] = {&BuiltInVariable::kpt01Y, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01Z00D00B[3] = {&BuiltInVariable::kpt01Z, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01Z00D00D00D[4] = {&BuiltInVariable::kpt01Z, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01Z00D00E00E[4] = {&BuiltInVariable::kpt01Z, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01a10D00B[3] = {&BuiltInVariable::kpt01a, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01a10D00D00D[4] = {&BuiltInVariable::kpt01a, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01a10D00E00E[4] = {&BuiltInVariable::kpt01a, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01b10D00D00B[4] = {&BuiltInVariable::kpt01b, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01b10D00D00D00D[5] = {
+ &BuiltInVariable::kpt01b, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01b10D00D00E00E[5] = {
+ &BuiltInVariable::kpt01b, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01c20D00D00B[4] = {&BuiltInVariable::kpt01c, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01c20D00D00D00D[5] = {
+ &BuiltInVariable::kpt01c, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01c20D00D00E00E[5] = {
+ &BuiltInVariable::kpt01c, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01d20D00B[3] = {&BuiltInVariable::kpt01d, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01d20D00D00D[4] = {&BuiltInVariable::kpt01d, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01d20D00E00E[4] = {&BuiltInVariable::kpt01d, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01d20D30E[3] = {&BuiltInVariable::kpt01d, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01e10D00B[3] = {&BuiltInVariable::kpt01e, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01e10D00D00D[4] = {&BuiltInVariable::kpt01e, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01e10D00E00E[4] = {&BuiltInVariable::kpt01e, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01f00D00B[3] = {&BuiltInVariable::kpt01f, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01f00D00D00D[4] = {&BuiltInVariable::kpt01f, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01f00D00E00E[4] = {&BuiltInVariable::kpt01f, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01f00D30E[3] = {&BuiltInVariable::kpt01f, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01g30B[2] = {&BuiltInVariable::kpt01g, &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01h30D[2] = {&BuiltInVariable::kpt01h, &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01i30E[2] = {&BuiltInVariable::kpt01i, &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01j[1] = {&BuiltInVariable::kpt01j};
+constexpr const TVariable *p01k[1] = {&BuiltInVariable::kpt01k};
+constexpr const TVariable *p01l[1] = {&BuiltInVariable::kpt01l};
+constexpr const TVariable *p01m00D[2] = {&BuiltInVariable::kpt01m, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01n00D[2] = {&BuiltInVariable::kpt01n, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01o00D[2] = {&BuiltInVariable::kpt01o, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10B00B00B[3] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p10B00D[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10B10B00B[3] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p10B10B10B[3] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B};
+constexpr const TVariable *p10B10B10F[3] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10F};
+constexpr const TVariable *p10B10D[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p10B20B[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p10B30B[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt30B};
+constexpr const TVariable *p10B_o_10B[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt_o_10B};
+constexpr const TVariable *p10B_o_10D[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt_o_10D};
+constexpr const TVariable *p10D00D00D[3] = {&BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10D10D00D00D[4] = {&BuiltInVariable::kpt10D, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10D10D10D[3] = {&BuiltInVariable::kpt10D, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt10D};
+constexpr const TVariable *p10D10D10F[3] = {&BuiltInVariable::kpt10D, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt10F};
+constexpr const TVariable *p10D10D_o_10D_o_10D[4] = {
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt_o_10D,
+ &BuiltInVariable::kpt_o_10D};
+constexpr const TVariable *p10E00D00D[3] = {&BuiltInVariable::kpt10E, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10E00E00E[3] = {&BuiltInVariable::kpt10E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00E};
+constexpr const TVariable *p10E10E00D00D[4] = {&BuiltInVariable::kpt10E, &BuiltInVariable::kpt10E,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10E10E10E[3] = {&BuiltInVariable::kpt10E, &BuiltInVariable::kpt10E,
+ &BuiltInVariable::kpt10E};
+constexpr const TVariable *p10E10E10F[3] = {&BuiltInVariable::kpt10E, &BuiltInVariable::kpt10E,
+ &BuiltInVariable::kpt10F};
+constexpr const TVariable *p10E10E_o_10E_o_10E[4] = {
+ &BuiltInVariable::kpt10E, &BuiltInVariable::kpt10E, &BuiltInVariable::kpt_o_10E,
+ &BuiltInVariable::kpt_o_10E};
+constexpr const TVariable *p10F10F10F[3] = {&BuiltInVariable::kpt10F, &BuiltInVariable::kpt10F,
+ &BuiltInVariable::kpt10F};
+constexpr const TVariable *p20B00B00B[3] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p20B00D[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p20B00H[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt00H};
+constexpr const TVariable *p20B10B[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B};
+constexpr const TVariable *p20B20B00B[3] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p20B20B20B[3] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B};
+constexpr const TVariable *p20B20B20F[3] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20F};
+constexpr const TVariable *p20B20D[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p20B30B[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt30B};
+constexpr const TVariable *p20B_o_20B[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt_o_20B};
+constexpr const TVariable *p20B_o_20D[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt_o_20D};
+constexpr const TVariable *p20D00D00D[3] = {&BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p20D20D00D00D[4] = {&BuiltInVariable::kpt20D, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p20D20D20D[3] = {&BuiltInVariable::kpt20D, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt20D};
+constexpr const TVariable *p20D20D20F[3] = {&BuiltInVariable::kpt20D, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt20F};
+constexpr const TVariable *p20D20D_o_20D_o_20D[4] = {
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt_o_20D,
+ &BuiltInVariable::kpt_o_20D};
+constexpr const TVariable *p20E00D00D[3] = {&BuiltInVariable::kpt20E, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p20E00E00E[3] = {&BuiltInVariable::kpt20E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00E};
+constexpr const TVariable *p20E20E00D00D[4] = {&BuiltInVariable::kpt20E, &BuiltInVariable::kpt20E,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p20E20E20E[3] = {&BuiltInVariable::kpt20E, &BuiltInVariable::kpt20E,
+ &BuiltInVariable::kpt20E};
+constexpr const TVariable *p20E20E20F[3] = {&BuiltInVariable::kpt20E, &BuiltInVariable::kpt20E,
+ &BuiltInVariable::kpt20F};
+constexpr const TVariable *p20E20E_o_20E_o_20E[4] = {
+ &BuiltInVariable::kpt20E, &BuiltInVariable::kpt20E, &BuiltInVariable::kpt_o_20E,
+ &BuiltInVariable::kpt_o_20E};
+constexpr const TVariable *p20F20F20F[3] = {&BuiltInVariable::kpt20F, &BuiltInVariable::kpt20F,
+ &BuiltInVariable::kpt20F};
+constexpr const TVariable *p30B00B00B[3] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p30B00D[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p30B10B[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B};
+constexpr const TVariable *p30B20B[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p30B30B00B[3] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p30B30B30B[3] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p30B30B30F[3] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt30F};
+constexpr const TVariable *p30B30D[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt30D};
+constexpr const TVariable *p30B_o_30B[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt_o_30B};
+constexpr const TVariable *p30B_o_30D[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt_o_30D};
+constexpr const TVariable *p30D00D00D[3] = {&BuiltInVariable::kpt30D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p30D30D00D00D[4] = {&BuiltInVariable::kpt30D, &BuiltInVariable::kpt30D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p30D30D30D[3] = {&BuiltInVariable::kpt30D, &BuiltInVariable::kpt30D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p30D30D30F[3] = {&BuiltInVariable::kpt30D, &BuiltInVariable::kpt30D,
+ &BuiltInVariable::kpt30F};
+constexpr const TVariable *p30D30D_o_30D_o_30D[4] = {
+ &BuiltInVariable::kpt30D, &BuiltInVariable::kpt30D, &BuiltInVariable::kpt_o_30D,
+ &BuiltInVariable::kpt_o_30D};
+constexpr const TVariable *p30E00D00D[3] = {&BuiltInVariable::kpt30E, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p30E00E00E[3] = {&BuiltInVariable::kpt30E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00E};
+constexpr const TVariable *p30E30E00D00D[4] = {&BuiltInVariable::kpt30E, &BuiltInVariable::kpt30E,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p30E30E30E[3] = {&BuiltInVariable::kpt30E, &BuiltInVariable::kpt30E,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p30E30E30F[3] = {&BuiltInVariable::kpt30E, &BuiltInVariable::kpt30E,
+ &BuiltInVariable::kpt30F};
+constexpr const TVariable *p30E30E_o_30E_o_30E[4] = {
+ &BuiltInVariable::kpt30E, &BuiltInVariable::kpt30E, &BuiltInVariable::kpt_o_30E,
+ &BuiltInVariable::kpt_o_30E};
+constexpr const TVariable *p30F30F30F[3] = {&BuiltInVariable::kpt30F, &BuiltInVariable::kpt30F,
+ &BuiltInVariable::kpt30F};
+constexpr const TVariable *p50B50B[2] = {&BuiltInVariable::kpt50B, &BuiltInVariable::kpt50B};
+constexpr const TVariable *p60B60B[2] = {&BuiltInVariable::kpt60B, &BuiltInVariable::kpt60B};
+constexpr const TVariable *p70B70B[2] = {&BuiltInVariable::kpt70B, &BuiltInVariable::kpt70B};
+constexpr const TVariable *p90B90B[2] = {&BuiltInVariable::kpt90B, &BuiltInVariable::kpt90B};
+constexpr const TVariable *pA0BA0B[2] = {&BuiltInVariable::kptA0B, &BuiltInVariable::kptA0B};
+constexpr const TVariable *pB0BB0B[2] = {&BuiltInVariable::kptB0B, &BuiltInVariable::kptB0B};
+constexpr const TVariable *pD0BD0B[2] = {&BuiltInVariable::kptD0B, &BuiltInVariable::kptD0B};
+constexpr const TVariable *pE0BE0B[2] = {&BuiltInVariable::kptE0B, &BuiltInVariable::kptE0B};
+constexpr const TVariable *pF0BF0B[2] = {&BuiltInVariable::kptF0B, &BuiltInVariable::kptF0B};
+constexpr const TVariable *p_io_00D00D00D[3] = {&BuiltInVariable::kpt_io_00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p_io_00E00E00E[3] = {&BuiltInVariable::kpt_io_00E,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+
+} // namespace BuiltInParameters
+
+// TODO(oetuaho): Would be nice to make this a class instead of a namespace so that we could friend
+// this from TFunction. Now symbol constructors taking an id have to be public even though they're
+// not supposed to be accessible from outside of here. http://anglebug.com/2390
+namespace Func
+{
+
+constexpr const TFunction radians_00B(BuiltInId::radians_Float1,
+ BuiltInName::radians,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpRadians,
+ true);
+constexpr const TFunction radians_10B(BuiltInId::radians_Float2,
+ BuiltInName::radians,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpRadians,
+ true);
+constexpr const TFunction radians_20B(BuiltInId::radians_Float3,
+ BuiltInName::radians,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpRadians,
+ true);
+constexpr const TFunction radians_30B(BuiltInId::radians_Float4,
+ BuiltInName::radians,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpRadians,
+ true);
+constexpr const TFunction degrees_00B(BuiltInId::degrees_Float1,
+ BuiltInName::degrees,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDegrees,
+ true);
+constexpr const TFunction degrees_10B(BuiltInId::degrees_Float2,
+ BuiltInName::degrees,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpDegrees,
+ true);
+constexpr const TFunction degrees_20B(BuiltInId::degrees_Float3,
+ BuiltInName::degrees,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpDegrees,
+ true);
+constexpr const TFunction degrees_30B(BuiltInId::degrees_Float4,
+ BuiltInName::degrees,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpDegrees,
+ true);
+constexpr const TFunction sin_00B(BuiltInId::sin_Float1,
+ BuiltInName::sin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSin,
+ true);
+constexpr const TFunction sin_10B(BuiltInId::sin_Float2,
+ BuiltInName::sin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSin,
+ true);
+constexpr const TFunction sin_20B(BuiltInId::sin_Float3,
+ BuiltInName::sin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSin,
+ true);
+constexpr const TFunction sin_30B(BuiltInId::sin_Float4,
+ BuiltInName::sin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSin,
+ true);
+constexpr const TFunction cos_00B(BuiltInId::cos_Float1,
+ BuiltInName::cos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpCos,
+ true);
+constexpr const TFunction cos_10B(BuiltInId::cos_Float2,
+ BuiltInName::cos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpCos,
+ true);
+constexpr const TFunction cos_20B(BuiltInId::cos_Float3,
+ BuiltInName::cos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpCos,
+ true);
+constexpr const TFunction cos_30B(BuiltInId::cos_Float4,
+ BuiltInName::cos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpCos,
+ true);
+constexpr const TFunction tan_00B(BuiltInId::tan_Float1,
+ BuiltInName::tan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTan,
+ true);
+constexpr const TFunction tan_10B(BuiltInId::tan_Float2,
+ BuiltInName::tan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTan,
+ true);
+constexpr const TFunction tan_20B(BuiltInId::tan_Float3,
+ BuiltInName::tan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTan,
+ true);
+constexpr const TFunction tan_30B(BuiltInId::tan_Float4,
+ BuiltInName::tan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTan,
+ true);
+constexpr const TFunction asin_00B(BuiltInId::asin_Float1,
+ BuiltInName::asin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAsin,
+ true);
+constexpr const TFunction asin_10B(BuiltInId::asin_Float2,
+ BuiltInName::asin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAsin,
+ true);
+constexpr const TFunction asin_20B(BuiltInId::asin_Float3,
+ BuiltInName::asin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAsin,
+ true);
+constexpr const TFunction asin_30B(BuiltInId::asin_Float4,
+ BuiltInName::asin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAsin,
+ true);
+constexpr const TFunction acos_00B(BuiltInId::acos_Float1,
+ BuiltInName::acos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAcos,
+ true);
+constexpr const TFunction acos_10B(BuiltInId::acos_Float2,
+ BuiltInName::acos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAcos,
+ true);
+constexpr const TFunction acos_20B(BuiltInId::acos_Float3,
+ BuiltInName::acos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAcos,
+ true);
+constexpr const TFunction acos_30B(BuiltInId::acos_Float4,
+ BuiltInName::acos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAcos,
+ true);
+constexpr const TFunction atan_00B00B(BuiltInId::atan_Float1_Float1,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_10B10B(BuiltInId::atan_Float2_Float2,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_20B20B(BuiltInId::atan_Float3_Float3,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_30B30B(BuiltInId::atan_Float4_Float4,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_00B(BuiltInId::atan_Float1,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_10B(BuiltInId::atan_Float2,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_20B(BuiltInId::atan_Float3,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_30B(BuiltInId::atan_Float4,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction sinh_00B(BuiltInId::sinh_Float1,
+ BuiltInName::sinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSinh,
+ true);
+constexpr const TFunction sinh_10B(BuiltInId::sinh_Float2,
+ BuiltInName::sinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSinh,
+ true);
+constexpr const TFunction sinh_20B(BuiltInId::sinh_Float3,
+ BuiltInName::sinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSinh,
+ true);
+constexpr const TFunction sinh_30B(BuiltInId::sinh_Float4,
+ BuiltInName::sinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSinh,
+ true);
+constexpr const TFunction cosh_00B(BuiltInId::cosh_Float1,
+ BuiltInName::cosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpCosh,
+ true);
+constexpr const TFunction cosh_10B(BuiltInId::cosh_Float2,
+ BuiltInName::cosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpCosh,
+ true);
+constexpr const TFunction cosh_20B(BuiltInId::cosh_Float3,
+ BuiltInName::cosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpCosh,
+ true);
+constexpr const TFunction cosh_30B(BuiltInId::cosh_Float4,
+ BuiltInName::cosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpCosh,
+ true);
+constexpr const TFunction tanh_00B(BuiltInId::tanh_Float1,
+ BuiltInName::tanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTanh,
+ true);
+constexpr const TFunction tanh_10B(BuiltInId::tanh_Float2,
+ BuiltInName::tanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTanh,
+ true);
+constexpr const TFunction tanh_20B(BuiltInId::tanh_Float3,
+ BuiltInName::tanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTanh,
+ true);
+constexpr const TFunction tanh_30B(BuiltInId::tanh_Float4,
+ BuiltInName::tanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTanh,
+ true);
+constexpr const TFunction asinh_00B(BuiltInId::asinh_Float1,
+ BuiltInName::asinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAsinh,
+ true);
+constexpr const TFunction asinh_10B(BuiltInId::asinh_Float2,
+ BuiltInName::asinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAsinh,
+ true);
+constexpr const TFunction asinh_20B(BuiltInId::asinh_Float3,
+ BuiltInName::asinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAsinh,
+ true);
+constexpr const TFunction asinh_30B(BuiltInId::asinh_Float4,
+ BuiltInName::asinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAsinh,
+ true);
+constexpr const TFunction acosh_00B(BuiltInId::acosh_Float1,
+ BuiltInName::acosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAcosh,
+ true);
+constexpr const TFunction acosh_10B(BuiltInId::acosh_Float2,
+ BuiltInName::acosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAcosh,
+ true);
+constexpr const TFunction acosh_20B(BuiltInId::acosh_Float3,
+ BuiltInName::acosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAcosh,
+ true);
+constexpr const TFunction acosh_30B(BuiltInId::acosh_Float4,
+ BuiltInName::acosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAcosh,
+ true);
+constexpr const TFunction atanh_00B(BuiltInId::atanh_Float1,
+ BuiltInName::atanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtanh,
+ true);
+constexpr const TFunction atanh_10B(BuiltInId::atanh_Float2,
+ BuiltInName::atanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAtanh,
+ true);
+constexpr const TFunction atanh_20B(BuiltInId::atanh_Float3,
+ BuiltInName::atanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAtanh,
+ true);
+constexpr const TFunction atanh_30B(BuiltInId::atanh_Float4,
+ BuiltInName::atanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAtanh,
+ true);
+constexpr const TFunction pow_00B00B(BuiltInId::pow_Float1_Float1,
+ BuiltInName::pow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPow,
+ true);
+constexpr const TFunction pow_10B10B(BuiltInId::pow_Float2_Float2,
+ BuiltInName::pow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpPow,
+ true);
+constexpr const TFunction pow_20B20B(BuiltInId::pow_Float3_Float3,
+ BuiltInName::pow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpPow,
+ true);
+constexpr const TFunction pow_30B30B(BuiltInId::pow_Float4_Float4,
+ BuiltInName::pow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpPow,
+ true);
+constexpr const TFunction exp_00B(BuiltInId::exp_Float1,
+ BuiltInName::exp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpExp,
+ true);
+constexpr const TFunction exp_10B(BuiltInId::exp_Float2,
+ BuiltInName::exp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpExp,
+ true);
+constexpr const TFunction exp_20B(BuiltInId::exp_Float3,
+ BuiltInName::exp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpExp,
+ true);
+constexpr const TFunction exp_30B(BuiltInId::exp_Float4,
+ BuiltInName::exp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpExp,
+ true);
+constexpr const TFunction log_00B(BuiltInId::log_Float1,
+ BuiltInName::log,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLog,
+ true);
+constexpr const TFunction log_10B(BuiltInId::log_Float2,
+ BuiltInName::log,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLog,
+ true);
+constexpr const TFunction log_20B(BuiltInId::log_Float3,
+ BuiltInName::log,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLog,
+ true);
+constexpr const TFunction log_30B(BuiltInId::log_Float4,
+ BuiltInName::log,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLog,
+ true);
+constexpr const TFunction exp2_00B(BuiltInId::exp2_Float1,
+ BuiltInName::exp2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpExp2,
+ true);
+constexpr const TFunction exp2_10B(BuiltInId::exp2_Float2,
+ BuiltInName::exp2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpExp2,
+ true);
+constexpr const TFunction exp2_20B(BuiltInId::exp2_Float3,
+ BuiltInName::exp2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpExp2,
+ true);
+constexpr const TFunction exp2_30B(BuiltInId::exp2_Float4,
+ BuiltInName::exp2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpExp2,
+ true);
+constexpr const TFunction log2_00B(BuiltInId::log2_Float1,
+ BuiltInName::log2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLog2,
+ true);
+constexpr const TFunction log2_10B(BuiltInId::log2_Float2,
+ BuiltInName::log2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLog2,
+ true);
+constexpr const TFunction log2_20B(BuiltInId::log2_Float3,
+ BuiltInName::log2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLog2,
+ true);
+constexpr const TFunction log2_30B(BuiltInId::log2_Float4,
+ BuiltInName::log2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLog2,
+ true);
+constexpr const TFunction sqrt_00B(BuiltInId::sqrt_Float1,
+ BuiltInName::sqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSqrt,
+ true);
+constexpr const TFunction sqrt_10B(BuiltInId::sqrt_Float2,
+ BuiltInName::sqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSqrt,
+ true);
+constexpr const TFunction sqrt_20B(BuiltInId::sqrt_Float3,
+ BuiltInName::sqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSqrt,
+ true);
+constexpr const TFunction sqrt_30B(BuiltInId::sqrt_Float4,
+ BuiltInName::sqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSqrt,
+ true);
+constexpr const TFunction inversesqrt_00B(
+ BuiltInId::inversesqrt_Float1,
+ BuiltInName::inversesqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInversesqrt,
+ true);
+constexpr const TFunction inversesqrt_10B(
+ BuiltInId::inversesqrt_Float2,
+ BuiltInName::inversesqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInversesqrt,
+ true);
+constexpr const TFunction inversesqrt_20B(
+ BuiltInId::inversesqrt_Float3,
+ BuiltInName::inversesqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInversesqrt,
+ true);
+constexpr const TFunction inversesqrt_30B(
+ BuiltInId::inversesqrt_Float4,
+ BuiltInName::inversesqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInversesqrt,
+ true);
+constexpr const TFunction abs_00B(BuiltInId::abs_Float1,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_10B(BuiltInId::abs_Float2,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_20B(BuiltInId::abs_Float3,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_30B(BuiltInId::abs_Float4,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_00D(BuiltInId::abs_Int1,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_10D(BuiltInId::abs_Int2,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_20D(BuiltInId::abs_Int3,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_30D(BuiltInId::abs_Int4,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction sign_00B(BuiltInId::sign_Float1,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_10B(BuiltInId::sign_Float2,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_20B(BuiltInId::sign_Float3,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_30B(BuiltInId::sign_Float4,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_00D(BuiltInId::sign_Int1,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_10D(BuiltInId::sign_Int2,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_20D(BuiltInId::sign_Int3,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_30D(BuiltInId::sign_Int4,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction floor_00B(BuiltInId::floor_Float1,
+ BuiltInName::floor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFloor,
+ true);
+constexpr const TFunction floor_10B(BuiltInId::floor_Float2,
+ BuiltInName::floor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFloor,
+ true);
+constexpr const TFunction floor_20B(BuiltInId::floor_Float3,
+ BuiltInName::floor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFloor,
+ true);
+constexpr const TFunction floor_30B(BuiltInId::floor_Float4,
+ BuiltInName::floor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFloor,
+ true);
+constexpr const TFunction trunc_00B(BuiltInId::trunc_Float1,
+ BuiltInName::trunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTrunc,
+ true);
+constexpr const TFunction trunc_10B(BuiltInId::trunc_Float2,
+ BuiltInName::trunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTrunc,
+ true);
+constexpr const TFunction trunc_20B(BuiltInId::trunc_Float3,
+ BuiltInName::trunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTrunc,
+ true);
+constexpr const TFunction trunc_30B(BuiltInId::trunc_Float4,
+ BuiltInName::trunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTrunc,
+ true);
+constexpr const TFunction round_00B(BuiltInId::round_Float1,
+ BuiltInName::round,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpRound,
+ true);
+constexpr const TFunction round_10B(BuiltInId::round_Float2,
+ BuiltInName::round,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpRound,
+ true);
+constexpr const TFunction round_20B(BuiltInId::round_Float3,
+ BuiltInName::round,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpRound,
+ true);
+constexpr const TFunction round_30B(BuiltInId::round_Float4,
+ BuiltInName::round,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpRound,
+ true);
+constexpr const TFunction roundEven_00B(BuiltInId::roundEven_Float1,
+ BuiltInName::roundEven,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpRoundEven,
+ true);
+constexpr const TFunction roundEven_10B(BuiltInId::roundEven_Float2,
+ BuiltInName::roundEven,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpRoundEven,
+ true);
+constexpr const TFunction roundEven_20B(BuiltInId::roundEven_Float3,
+ BuiltInName::roundEven,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpRoundEven,
+ true);
+constexpr const TFunction roundEven_30B(BuiltInId::roundEven_Float4,
+ BuiltInName::roundEven,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpRoundEven,
+ true);
+constexpr const TFunction ceil_00B(BuiltInId::ceil_Float1,
+ BuiltInName::ceil,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpCeil,
+ true);
+constexpr const TFunction ceil_10B(BuiltInId::ceil_Float2,
+ BuiltInName::ceil,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpCeil,
+ true);
+constexpr const TFunction ceil_20B(BuiltInId::ceil_Float3,
+ BuiltInName::ceil,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpCeil,
+ true);
+constexpr const TFunction ceil_30B(BuiltInId::ceil_Float4,
+ BuiltInName::ceil,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpCeil,
+ true);
+constexpr const TFunction fract_00B(BuiltInId::fract_Float1,
+ BuiltInName::fract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFract,
+ true);
+constexpr const TFunction fract_10B(BuiltInId::fract_Float2,
+ BuiltInName::fract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFract,
+ true);
+constexpr const TFunction fract_20B(BuiltInId::fract_Float3,
+ BuiltInName::fract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFract,
+ true);
+constexpr const TFunction fract_30B(BuiltInId::fract_Float4,
+ BuiltInName::fract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFract,
+ true);
+constexpr const TFunction mod_00B00B(BuiltInId::mod_Float1_Float1,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_10B00B(BuiltInId::mod_Float2_Float1,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_20B00B(BuiltInId::mod_Float3_Float1,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_30B00B(BuiltInId::mod_Float4_Float1,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_10B10B(BuiltInId::mod_Float2_Float2,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_20B20B(BuiltInId::mod_Float3_Float3,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_30B30B(BuiltInId::mod_Float4_Float4,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction min_00B00B(BuiltInId::min_Float1_Float1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10B00B(BuiltInId::min_Float2_Float1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20B00B(BuiltInId::min_Float3_Float1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30B00B(BuiltInId::min_Float4_Float1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10B10B(BuiltInId::min_Float2_Float2,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20B20B(BuiltInId::min_Float3_Float3,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30B30B(BuiltInId::min_Float4_Float4,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_00D00D(BuiltInId::min_Int1_Int1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10D10D(BuiltInId::min_Int2_Int2,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20D20D(BuiltInId::min_Int3_Int3,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30D30D(BuiltInId::min_Int4_Int4,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10D00D(BuiltInId::min_Int2_Int1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20D00D(BuiltInId::min_Int3_Int1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30D00D(BuiltInId::min_Int4_Int1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_00E00E(BuiltInId::min_UInt1_UInt1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10E10E(BuiltInId::min_UInt2_UInt2,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20E20E(BuiltInId::min_UInt3_UInt3,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30E30E(BuiltInId::min_UInt4_UInt4,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10E00E(BuiltInId::min_UInt2_UInt1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20E00E(BuiltInId::min_UInt3_UInt1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30E00E(BuiltInId::min_UInt4_UInt1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction max_00B00B(BuiltInId::max_Float1_Float1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10B00B(BuiltInId::max_Float2_Float1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20B00B(BuiltInId::max_Float3_Float1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30B00B(BuiltInId::max_Float4_Float1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10B10B(BuiltInId::max_Float2_Float2,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20B20B(BuiltInId::max_Float3_Float3,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30B30B(BuiltInId::max_Float4_Float4,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_00D00D(BuiltInId::max_Int1_Int1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10D10D(BuiltInId::max_Int2_Int2,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20D20D(BuiltInId::max_Int3_Int3,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30D30D(BuiltInId::max_Int4_Int4,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10D00D(BuiltInId::max_Int2_Int1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20D00D(BuiltInId::max_Int3_Int1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30D00D(BuiltInId::max_Int4_Int1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_00E00E(BuiltInId::max_UInt1_UInt1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10E10E(BuiltInId::max_UInt2_UInt2,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20E20E(BuiltInId::max_UInt3_UInt3,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30E30E(BuiltInId::max_UInt4_UInt4,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10E00E(BuiltInId::max_UInt2_UInt1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20E00E(BuiltInId::max_UInt3_UInt1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30E00E(BuiltInId::max_UInt4_UInt1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction clamp_00B00B00B(
+ BuiltInId::clamp_Float1_Float1_Float1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10B00B00B(
+ BuiltInId::clamp_Float2_Float1_Float1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20B00B00B(
+ BuiltInId::clamp_Float3_Float1_Float1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30B00B00B(
+ BuiltInId::clamp_Float4_Float1_Float1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10B10B10B(
+ BuiltInId::clamp_Float2_Float2_Float2,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20B20B20B(
+ BuiltInId::clamp_Float3_Float3_Float3,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30B30B30B(
+ BuiltInId::clamp_Float4_Float4_Float4,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_00D00D00D(BuiltInId::clamp_Int1_Int1_Int1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10D00D00D(BuiltInId::clamp_Int2_Int1_Int1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20D00D00D(BuiltInId::clamp_Int3_Int1_Int1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30D00D00D(BuiltInId::clamp_Int4_Int1_Int1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10D10D10D(BuiltInId::clamp_Int2_Int2_Int2,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20D20D20D(BuiltInId::clamp_Int3_Int3_Int3,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30D30D30D(BuiltInId::clamp_Int4_Int4_Int4,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D30D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_00E00E00E(BuiltInId::clamp_UInt1_UInt1_UInt1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10E00E00E(BuiltInId::clamp_UInt2_UInt1_UInt1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20E00E00E(BuiltInId::clamp_UInt3_UInt1_UInt1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30E00E00E(BuiltInId::clamp_UInt4_UInt1_UInt1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10E10E10E(BuiltInId::clamp_UInt2_UInt2_UInt2,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E10E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20E20E20E(BuiltInId::clamp_UInt3_UInt3_UInt3,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E20E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30E30E30E(BuiltInId::clamp_UInt4_UInt4_UInt4,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E30E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction mix_00B00B00B(BuiltInId::mix_Float1_Float1_Float1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10B10B00B(BuiltInId::mix_Float2_Float2_Float1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20B20B00B(BuiltInId::mix_Float3_Float3_Float1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30B30B00B(BuiltInId::mix_Float4_Float4_Float1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10B10B10B(BuiltInId::mix_Float2_Float2_Float2,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20B20B20B(BuiltInId::mix_Float3_Float3_Float3,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30B30B30B(BuiltInId::mix_Float4_Float4_Float4,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_00B00B00F(BuiltInId::mix_Float1_Float1_Bool1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00F,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10B10B10F(BuiltInId::mix_Float2_Float2_Bool2,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10F,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20B20B20F(BuiltInId::mix_Float3_Float3_Bool3,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20F,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30B30B30F(BuiltInId::mix_Float4_Float4_Bool4,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30F,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_00D00D00F(BuiltInId::mix_Int1_Int1_Bool1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00F,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10D10D10F(BuiltInId::mix_Int2_Int2_Bool2,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D10F,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20D20D20F(BuiltInId::mix_Int3_Int3_Bool3,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D20F,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30D30D30F(BuiltInId::mix_Int4_Int4_Bool4,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D30F,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_00E00E00F(BuiltInId::mix_UInt1_UInt1_Bool1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E00F,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10E10E10F(BuiltInId::mix_UInt2_UInt2_Bool2,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E10F,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20E20E20F(BuiltInId::mix_UInt3_UInt3_Bool3,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E20F,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30E30E30F(BuiltInId::mix_UInt4_UInt4_Bool4,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E30F,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_00F00F00F(BuiltInId::mix_Bool1_Bool1_Bool1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00F00F00F,
+ 3,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10F10F10F(BuiltInId::mix_Bool2_Bool2_Bool2,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 3,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20F20F20F(BuiltInId::mix_Bool3_Bool3_Bool3,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 3,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30F30F30F(BuiltInId::mix_Bool4_Bool4_Bool4,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 3,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction step_00B00B(BuiltInId::step_Float1_Float1,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_10B10B(BuiltInId::step_Float2_Float2,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_20B20B(BuiltInId::step_Float3_Float3,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_30B30B(BuiltInId::step_Float4_Float4,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_00B10B(BuiltInId::step_Float1_Float2,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_00B20B(BuiltInId::step_Float1_Float3,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_00B30B(BuiltInId::step_Float1_Float4,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction smoothstep_00B00B00B(
+ BuiltInId::smoothstep_Float1_Float1_Float1,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_10B10B10B(
+ BuiltInId::smoothstep_Float2_Float2_Float2,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_20B20B20B(
+ BuiltInId::smoothstep_Float3_Float3_Float3,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_30B30B30B(
+ BuiltInId::smoothstep_Float4_Float4_Float4,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_00B00B10B(
+ BuiltInId::smoothstep_Float1_Float1_Float2,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_00B00B20B(
+ BuiltInId::smoothstep_Float1_Float1_Float3,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_00B00B30B(
+ BuiltInId::smoothstep_Float1_Float1_Float4,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction modf_00B00B(BuiltInId::modf_Float1_Float1,
+ BuiltInName::modf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B_o_00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpModf,
+ false);
+constexpr const TFunction modf_10B10B(BuiltInId::modf_Float2_Float2,
+ BuiltInName::modf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B_o_10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpModf,
+ false);
+constexpr const TFunction modf_20B20B(BuiltInId::modf_Float3_Float3,
+ BuiltInName::modf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B_o_20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpModf,
+ false);
+constexpr const TFunction modf_30B30B(BuiltInId::modf_Float4_Float4,
+ BuiltInName::modf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B_o_30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpModf,
+ false);
+constexpr const TFunction isnan_00B(BuiltInId::isnan_Float1,
+ BuiltInName::isnan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpIsnan,
+ true);
+constexpr const TFunction isnan_10B(BuiltInId::isnan_Float2,
+ BuiltInName::isnan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpIsnan,
+ true);
+constexpr const TFunction isnan_20B(BuiltInId::isnan_Float3,
+ BuiltInName::isnan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpIsnan,
+ true);
+constexpr const TFunction isnan_30B(BuiltInId::isnan_Float4,
+ BuiltInName::isnan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpIsnan,
+ true);
+constexpr const TFunction isinf_00B(BuiltInId::isinf_Float1,
+ BuiltInName::isinf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpIsinf,
+ true);
+constexpr const TFunction isinf_10B(BuiltInId::isinf_Float2,
+ BuiltInName::isinf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpIsinf,
+ true);
+constexpr const TFunction isinf_20B(BuiltInId::isinf_Float3,
+ BuiltInName::isinf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpIsinf,
+ true);
+constexpr const TFunction isinf_30B(BuiltInId::isinf_Float4,
+ BuiltInName::isinf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpIsinf,
+ true);
+constexpr const TFunction floatBitsToInt_00B(
+ BuiltInId::floatBitsToInt_Float1,
+ BuiltInName::floatBitsToInt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFloatBitsToInt,
+ true);
+constexpr const TFunction floatBitsToInt_10B(
+ BuiltInId::floatBitsToInt_Float2,
+ BuiltInName::floatBitsToInt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFloatBitsToInt,
+ true);
+constexpr const TFunction floatBitsToInt_20B(
+ BuiltInId::floatBitsToInt_Float3,
+ BuiltInName::floatBitsToInt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFloatBitsToInt,
+ true);
+constexpr const TFunction floatBitsToInt_30B(
+ BuiltInId::floatBitsToInt_Float4,
+ BuiltInName::floatBitsToInt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFloatBitsToInt,
+ true);
+constexpr const TFunction floatBitsToUint_00B(
+ BuiltInId::floatBitsToUint_Float1,
+ BuiltInName::floatBitsToUint,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFloatBitsToUint,
+ true);
+constexpr const TFunction floatBitsToUint_10B(
+ BuiltInId::floatBitsToUint_Float2,
+ BuiltInName::floatBitsToUint,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFloatBitsToUint,
+ true);
+constexpr const TFunction floatBitsToUint_20B(
+ BuiltInId::floatBitsToUint_Float3,
+ BuiltInName::floatBitsToUint,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFloatBitsToUint,
+ true);
+constexpr const TFunction floatBitsToUint_30B(
+ BuiltInId::floatBitsToUint_Float4,
+ BuiltInName::floatBitsToUint,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFloatBitsToUint,
+ true);
+constexpr const TFunction intBitsToFloat_00D(
+ BuiltInId::intBitsToFloat_Int1,
+ BuiltInName::intBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpIntBitsToFloat,
+ true);
+constexpr const TFunction intBitsToFloat_10D(
+ BuiltInId::intBitsToFloat_Int2,
+ BuiltInName::intBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpIntBitsToFloat,
+ true);
+constexpr const TFunction intBitsToFloat_20D(
+ BuiltInId::intBitsToFloat_Int3,
+ BuiltInName::intBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpIntBitsToFloat,
+ true);
+constexpr const TFunction intBitsToFloat_30D(
+ BuiltInId::intBitsToFloat_Int4,
+ BuiltInName::intBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpIntBitsToFloat,
+ true);
+constexpr const TFunction uintBitsToFloat_00E(
+ BuiltInId::uintBitsToFloat_UInt1,
+ BuiltInName::uintBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUintBitsToFloat,
+ true);
+constexpr const TFunction uintBitsToFloat_10E(
+ BuiltInId::uintBitsToFloat_UInt2,
+ BuiltInName::uintBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUintBitsToFloat,
+ true);
+constexpr const TFunction uintBitsToFloat_20E(
+ BuiltInId::uintBitsToFloat_UInt3,
+ BuiltInName::uintBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpUintBitsToFloat,
+ true);
+constexpr const TFunction uintBitsToFloat_30E(
+ BuiltInId::uintBitsToFloat_UInt4,
+ BuiltInName::uintBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpUintBitsToFloat,
+ true);
+constexpr const TFunction fma_00B00B00B(BuiltInId::fma_Float1_Float1_Float1,
+ BuiltInName::fma,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fma_10B10B10B(BuiltInId::fma_Float2_Float2_Float2,
+ BuiltInName::fma,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fma_20B20B20B(BuiltInId::fma_Float3_Float3_Float3,
+ BuiltInName::fma,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fma_30B30B30B(BuiltInId::fma_Float4_Float4_Float4,
+ BuiltInName::fma,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fmaExt_00B00B00B(
+ BuiltInId::fmaExt_Float1_Float1_Float1,
+ BuiltInName::fmaExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fmaExt_10B10B10B(
+ BuiltInId::fmaExt_Float2_Float2_Float2,
+ BuiltInName::fmaExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fmaExt_20B20B20B(
+ BuiltInId::fmaExt_Float3_Float3_Float3,
+ BuiltInName::fmaExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fmaExt_30B30B30B(
+ BuiltInId::fmaExt_Float4_Float4_Float4,
+ BuiltInName::fmaExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction frexp_00B00D(BuiltInId::frexp_Float1_Int1,
+ BuiltInName::frexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B_o_00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFrexp,
+ false);
+constexpr const TFunction frexp_10B10D(BuiltInId::frexp_Float2_Int2,
+ BuiltInName::frexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B_o_10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFrexp,
+ false);
+constexpr const TFunction frexp_20B20D(BuiltInId::frexp_Float3_Int3,
+ BuiltInName::frexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B_o_20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFrexp,
+ false);
+constexpr const TFunction frexp_30B30D(BuiltInId::frexp_Float4_Int4,
+ BuiltInName::frexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B_o_30D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFrexp,
+ false);
+constexpr const TFunction ldexp_00B00D(BuiltInId::ldexp_Float1_Int1,
+ BuiltInName::ldexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLdexp,
+ true);
+constexpr const TFunction ldexp_10B10D(BuiltInId::ldexp_Float2_Int2,
+ BuiltInName::ldexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLdexp,
+ true);
+constexpr const TFunction ldexp_20B20D(BuiltInId::ldexp_Float3_Int3,
+ BuiltInName::ldexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLdexp,
+ true);
+constexpr const TFunction ldexp_30B30D(BuiltInId::ldexp_Float4_Int4,
+ BuiltInName::ldexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLdexp,
+ true);
+constexpr const TFunction packSnorm2x16_10B(
+ BuiltInId::packSnorm2x16_Float2,
+ BuiltInName::packSnorm2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPackSnorm2x16,
+ true);
+constexpr const TFunction packHalf2x16_10B(
+ BuiltInId::packHalf2x16_Float2,
+ BuiltInName::packHalf2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPackHalf2x16,
+ true);
+constexpr const TFunction unpackSnorm2x16_00E(
+ BuiltInId::unpackSnorm2x16_UInt1,
+ BuiltInName::unpackSnorm2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUnpackSnorm2x16,
+ true);
+constexpr const TFunction unpackHalf2x16_00E(
+ BuiltInId::unpackHalf2x16_UInt1,
+ BuiltInName::unpackHalf2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUnpackHalf2x16,
+ true);
+constexpr const TFunction packUnorm2x16_10B(
+ BuiltInId::packUnorm2x16_Float2,
+ BuiltInName::packUnorm2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPackUnorm2x16,
+ true);
+constexpr const TFunction unpackUnorm2x16_00E(
+ BuiltInId::unpackUnorm2x16_UInt1,
+ BuiltInName::unpackUnorm2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUnpackUnorm2x16,
+ true);
+constexpr const TFunction packUnorm4x8_30B(
+ BuiltInId::packUnorm4x8_Float4,
+ BuiltInName::packUnorm4x8,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPackUnorm4x8,
+ true);
+constexpr const TFunction packSnorm4x8_30B(
+ BuiltInId::packSnorm4x8_Float4,
+ BuiltInName::packSnorm4x8,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPackSnorm4x8,
+ true);
+constexpr const TFunction unpackUnorm4x8_00E(
+ BuiltInId::unpackUnorm4x8_UInt1,
+ BuiltInName::unpackUnorm4x8,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpUnpackUnorm4x8,
+ true);
+constexpr const TFunction unpackSnorm4x8_00E(
+ BuiltInId::unpackSnorm4x8_UInt1,
+ BuiltInName::unpackSnorm4x8,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpUnpackSnorm4x8,
+ true);
+constexpr const TFunction length_00B(BuiltInId::length_Float1,
+ BuiltInName::length,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLength,
+ true);
+constexpr const TFunction length_10B(BuiltInId::length_Float2,
+ BuiltInName::length,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLength,
+ true);
+constexpr const TFunction length_20B(BuiltInId::length_Float3,
+ BuiltInName::length,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLength,
+ true);
+constexpr const TFunction length_30B(BuiltInId::length_Float4,
+ BuiltInName::length,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLength,
+ true);
+constexpr const TFunction distance_00B00B(
+ BuiltInId::distance_Float1_Float1,
+ BuiltInName::distance,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDistance,
+ true);
+constexpr const TFunction distance_10B10B(
+ BuiltInId::distance_Float2_Float2,
+ BuiltInName::distance,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDistance,
+ true);
+constexpr const TFunction distance_20B20B(
+ BuiltInId::distance_Float3_Float3,
+ BuiltInName::distance,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDistance,
+ true);
+constexpr const TFunction distance_30B30B(
+ BuiltInId::distance_Float4_Float4,
+ BuiltInName::distance,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDistance,
+ true);
+constexpr const TFunction dot_00B00B(BuiltInId::dot_Float1_Float1,
+ BuiltInName::dot,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDot,
+ true);
+constexpr const TFunction dot_10B10B(BuiltInId::dot_Float2_Float2,
+ BuiltInName::dot,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDot,
+ true);
+constexpr const TFunction dot_20B20B(BuiltInId::dot_Float3_Float3,
+ BuiltInName::dot,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDot,
+ true);
+constexpr const TFunction dot_30B30B(BuiltInId::dot_Float4_Float4,
+ BuiltInName::dot,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDot,
+ true);
+constexpr const TFunction cross_20B20B(BuiltInId::cross_Float3_Float3,
+ BuiltInName::cross,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpCross,
+ true);
+constexpr const TFunction normalize_00B(BuiltInId::normalize_Float1,
+ BuiltInName::normalize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpNormalize,
+ true);
+constexpr const TFunction normalize_10B(BuiltInId::normalize_Float2,
+ BuiltInName::normalize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNormalize,
+ true);
+constexpr const TFunction normalize_20B(BuiltInId::normalize_Float3,
+ BuiltInName::normalize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNormalize,
+ true);
+constexpr const TFunction normalize_30B(BuiltInId::normalize_Float4,
+ BuiltInName::normalize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNormalize,
+ true);
+constexpr const TFunction faceforward_00B00B00B(
+ BuiltInId::faceforward_Float1_Float1_Float1,
+ BuiltInName::faceforward,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFaceforward,
+ true);
+constexpr const TFunction faceforward_10B10B10B(
+ BuiltInId::faceforward_Float2_Float2_Float2,
+ BuiltInName::faceforward,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFaceforward,
+ true);
+constexpr const TFunction faceforward_20B20B20B(
+ BuiltInId::faceforward_Float3_Float3_Float3,
+ BuiltInName::faceforward,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFaceforward,
+ true);
+constexpr const TFunction faceforward_30B30B30B(
+ BuiltInId::faceforward_Float4_Float4_Float4,
+ BuiltInName::faceforward,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFaceforward,
+ true);
+constexpr const TFunction reflect_00B00B(BuiltInId::reflect_Float1_Float1,
+ BuiltInName::reflect,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpReflect,
+ true);
+constexpr const TFunction reflect_10B10B(BuiltInId::reflect_Float2_Float2,
+ BuiltInName::reflect,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpReflect,
+ true);
+constexpr const TFunction reflect_20B20B(BuiltInId::reflect_Float3_Float3,
+ BuiltInName::reflect,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpReflect,
+ true);
+constexpr const TFunction reflect_30B30B(BuiltInId::reflect_Float4_Float4,
+ BuiltInName::reflect,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpReflect,
+ true);
+constexpr const TFunction refract_00B00B00B(
+ BuiltInId::refract_Float1_Float1_Float1,
+ BuiltInName::refract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpRefract,
+ true);
+constexpr const TFunction refract_10B10B00B(
+ BuiltInId::refract_Float2_Float2_Float1,
+ BuiltInName::refract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpRefract,
+ true);
+constexpr const TFunction refract_20B20B00B(
+ BuiltInId::refract_Float3_Float3_Float1,
+ BuiltInName::refract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpRefract,
+ true);
+constexpr const TFunction refract_30B30B00B(
+ BuiltInId::refract_Float4_Float4_Float1,
+ BuiltInName::refract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpRefract,
+ true);
+constexpr const TFunction matrixCompMult_50B50B(
+ BuiltInId::matrixCompMult_Float2x2_Float2x2,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p50B50B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_A0BA0B(
+ BuiltInId::matrixCompMult_Float3x3_Float3x3,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pA0BA0B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_F0BF0B(
+ BuiltInId::matrixCompMult_Float4x4_Float4x4,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pF0BF0B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_90B90B(
+ BuiltInId::matrixCompMult_Float2x3_Float2x3,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p90B90B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_60B60B(
+ BuiltInId::matrixCompMult_Float3x2_Float3x2,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p60B60B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_D0BD0B(
+ BuiltInId::matrixCompMult_Float2x4_Float2x4,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pD0BD0B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_70B70B(
+ BuiltInId::matrixCompMult_Float4x2_Float4x2,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p70B70B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_E0BE0B(
+ BuiltInId::matrixCompMult_Float3x4_Float3x4,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pE0BE0B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_B0BB0B(
+ BuiltInId::matrixCompMult_Float4x3_Float4x3,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pB0BB0B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction outerProduct_10B10B(
+ BuiltInId::outerProduct_Float2_Float2,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_20B20B(
+ BuiltInId::outerProduct_Float3_Float3,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_30B30B(
+ BuiltInId::outerProduct_Float4_Float4,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_20B10B(
+ BuiltInId::outerProduct_Float3_Float2,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_10B20B(
+ BuiltInId::outerProduct_Float2_Float3,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_30B10B(
+ BuiltInId::outerProduct_Float4_Float2,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_10B30B(
+ BuiltInId::outerProduct_Float2_Float4,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_30B20B(
+ BuiltInId::outerProduct_Float4_Float3,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_20B30B(
+ BuiltInId::outerProduct_Float3_Float4,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction transpose_50B(BuiltInId::transpose_Float2x2,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p50B50B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_A0B(BuiltInId::transpose_Float3x3,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pA0BA0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_F0B(BuiltInId::transpose_Float4x4,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pF0BF0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_60B(BuiltInId::transpose_Float3x2,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p60B60B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_90B(BuiltInId::transpose_Float2x3,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p90B90B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_70B(BuiltInId::transpose_Float4x2,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p70B70B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_D0B(BuiltInId::transpose_Float2x4,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pD0BD0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_B0B(BuiltInId::transpose_Float4x3,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pB0BB0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_E0B(BuiltInId::transpose_Float3x4,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pE0BE0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction determinant_50B(
+ BuiltInId::determinant_Float2x2,
+ BuiltInName::determinant,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p50B50B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDeterminant,
+ true);
+constexpr const TFunction determinant_A0B(
+ BuiltInId::determinant_Float3x3,
+ BuiltInName::determinant,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pA0BA0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDeterminant,
+ true);
+constexpr const TFunction determinant_F0B(
+ BuiltInId::determinant_Float4x4,
+ BuiltInName::determinant,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pF0BF0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDeterminant,
+ true);
+constexpr const TFunction inverse_50B(BuiltInId::inverse_Float2x2,
+ BuiltInName::inverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p50B50B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+ EOpInverse,
+ true);
+constexpr const TFunction inverse_A0B(BuiltInId::inverse_Float3x3,
+ BuiltInName::inverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pA0BA0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+ EOpInverse,
+ true);
+constexpr const TFunction inverse_F0B(BuiltInId::inverse_Float4x4,
+ BuiltInName::inverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pF0BF0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+ EOpInverse,
+ true);
+constexpr const TFunction lessThan_10B10B(BuiltInId::lessThan_Float2_Float2,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_20B20B(BuiltInId::lessThan_Float3_Float3,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_30B30B(BuiltInId::lessThan_Float4_Float4,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_10D10D(BuiltInId::lessThan_Int2_Int2,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_20D20D(BuiltInId::lessThan_Int3_Int3,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_30D30D(BuiltInId::lessThan_Int4_Int4,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_10E10E(BuiltInId::lessThan_UInt2_UInt2,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_20E20E(BuiltInId::lessThan_UInt3_UInt3,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_30E30E(BuiltInId::lessThan_UInt4_UInt4,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_10B10B(
+ BuiltInId::lessThanEqual_Float2_Float2,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_20B20B(
+ BuiltInId::lessThanEqual_Float3_Float3,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_30B30B(
+ BuiltInId::lessThanEqual_Float4_Float4,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_10D10D(
+ BuiltInId::lessThanEqual_Int2_Int2,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_20D20D(
+ BuiltInId::lessThanEqual_Int3_Int3,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_30D30D(
+ BuiltInId::lessThanEqual_Int4_Int4,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_10E10E(
+ BuiltInId::lessThanEqual_UInt2_UInt2,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_20E20E(
+ BuiltInId::lessThanEqual_UInt3_UInt3,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_30E30E(
+ BuiltInId::lessThanEqual_UInt4_UInt4,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThan_10B10B(
+ BuiltInId::greaterThan_Float2_Float2,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_20B20B(
+ BuiltInId::greaterThan_Float3_Float3,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_30B30B(
+ BuiltInId::greaterThan_Float4_Float4,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_10D10D(
+ BuiltInId::greaterThan_Int2_Int2,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_20D20D(
+ BuiltInId::greaterThan_Int3_Int3,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_30D30D(
+ BuiltInId::greaterThan_Int4_Int4,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_10E10E(
+ BuiltInId::greaterThan_UInt2_UInt2,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_20E20E(
+ BuiltInId::greaterThan_UInt3_UInt3,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_30E30E(
+ BuiltInId::greaterThan_UInt4_UInt4,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_10B10B(
+ BuiltInId::greaterThanEqual_Float2_Float2,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_20B20B(
+ BuiltInId::greaterThanEqual_Float3_Float3,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_30B30B(
+ BuiltInId::greaterThanEqual_Float4_Float4,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_10D10D(
+ BuiltInId::greaterThanEqual_Int2_Int2,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_20D20D(
+ BuiltInId::greaterThanEqual_Int3_Int3,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_30D30D(
+ BuiltInId::greaterThanEqual_Int4_Int4,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_10E10E(
+ BuiltInId::greaterThanEqual_UInt2_UInt2,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_20E20E(
+ BuiltInId::greaterThanEqual_UInt3_UInt3,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_30E30E(
+ BuiltInId::greaterThanEqual_UInt4_UInt4,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction equal_10B10B(BuiltInId::equal_Float2_Float2,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_20B20B(BuiltInId::equal_Float3_Float3,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_30B30B(BuiltInId::equal_Float4_Float4,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_10D10D(BuiltInId::equal_Int2_Int2,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_20D20D(BuiltInId::equal_Int3_Int3,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_30D30D(BuiltInId::equal_Int4_Int4,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_10E10E(BuiltInId::equal_UInt2_UInt2,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_20E20E(BuiltInId::equal_UInt3_UInt3,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_30E30E(BuiltInId::equal_UInt4_UInt4,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_10F10F(BuiltInId::equal_Bool2_Bool2,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_20F20F(BuiltInId::equal_Bool3_Bool3,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_30F30F(BuiltInId::equal_Bool4_Bool4,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_10B10B(BuiltInId::notEqual_Float2_Float2,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_20B20B(BuiltInId::notEqual_Float3_Float3,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_30B30B(BuiltInId::notEqual_Float4_Float4,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_10D10D(BuiltInId::notEqual_Int2_Int2,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_20D20D(BuiltInId::notEqual_Int3_Int3,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_30D30D(BuiltInId::notEqual_Int4_Int4,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_10E10E(BuiltInId::notEqual_UInt2_UInt2,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_20E20E(BuiltInId::notEqual_UInt3_UInt3,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_30E30E(BuiltInId::notEqual_UInt4_UInt4,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_10F10F(BuiltInId::notEqual_Bool2_Bool2,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_20F20F(BuiltInId::notEqual_Bool3_Bool3,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_30F30F(BuiltInId::notEqual_Bool4_Bool4,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction any_10F(BuiltInId::any_Bool2,
+ BuiltInName::any,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAny,
+ true);
+constexpr const TFunction any_20F(BuiltInId::any_Bool3,
+ BuiltInName::any,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAny,
+ true);
+constexpr const TFunction any_30F(BuiltInId::any_Bool4,
+ BuiltInName::any,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAny,
+ true);
+constexpr const TFunction all_10F(BuiltInId::all_Bool2,
+ BuiltInName::all,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAll,
+ true);
+constexpr const TFunction all_20F(BuiltInId::all_Bool3,
+ BuiltInName::all,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAll,
+ true);
+constexpr const TFunction all_30F(BuiltInId::all_Bool4,
+ BuiltInName::all,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAll,
+ true);
+constexpr const TFunction notFunc_10F(BuiltInId::notFunc_Bool2,
+ BuiltInName::notFunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNotComponentWise,
+ true);
+constexpr const TFunction notFunc_20F(BuiltInId::notFunc_Bool3,
+ BuiltInName::notFunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNotComponentWise,
+ true);
+constexpr const TFunction notFunc_30F(BuiltInId::notFunc_Bool4,
+ BuiltInName::notFunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNotComponentWise,
+ true);
+constexpr const TFunction bitfieldExtract_00D00D00D(
+ BuiltInId::bitfieldExtract_Int1_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_10D00D00D(
+ BuiltInId::bitfieldExtract_Int2_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_20D00D00D(
+ BuiltInId::bitfieldExtract_Int3_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_30D00D00D(
+ BuiltInId::bitfieldExtract_Int4_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_00E00D00D(
+ BuiltInId::bitfieldExtract_UInt1_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_10E00D00D(
+ BuiltInId::bitfieldExtract_UInt2_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_20E00D00D(
+ BuiltInId::bitfieldExtract_UInt3_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_30E00D00D(
+ BuiltInId::bitfieldExtract_UInt4_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldInsert_00D00D00D00D(
+ BuiltInId::bitfieldInsert_Int1_Int1_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_10D10D00D00D(
+ BuiltInId::bitfieldInsert_Int2_Int2_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_20D20D00D00D(
+ BuiltInId::bitfieldInsert_Int3_Int3_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_30D30D00D00D(
+ BuiltInId::bitfieldInsert_Int4_Int4_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_00E00E00D00D(
+ BuiltInId::bitfieldInsert_UInt1_UInt1_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E00D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_10E10E00D00D(
+ BuiltInId::bitfieldInsert_UInt2_UInt2_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_20E20E00D00D(
+ BuiltInId::bitfieldInsert_UInt3_UInt3_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_30E30E00D00D(
+ BuiltInId::bitfieldInsert_UInt4_UInt4_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldReverse_00D(
+ BuiltInId::bitfieldReverse_Int1,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_10D(
+ BuiltInId::bitfieldReverse_Int2,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_20D(
+ BuiltInId::bitfieldReverse_Int3,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_30D(
+ BuiltInId::bitfieldReverse_Int4,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_00E(
+ BuiltInId::bitfieldReverse_UInt1,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_10E(
+ BuiltInId::bitfieldReverse_UInt2,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_20E(
+ BuiltInId::bitfieldReverse_UInt3,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_30E(
+ BuiltInId::bitfieldReverse_UInt4,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitCount_00D(BuiltInId::bitCount_Int1,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_10D(BuiltInId::bitCount_Int2,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_20D(BuiltInId::bitCount_Int3,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_30D(BuiltInId::bitCount_Int4,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_00E(BuiltInId::bitCount_UInt1,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_10E(BuiltInId::bitCount_UInt2,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_20E(BuiltInId::bitCount_UInt3,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_30E(BuiltInId::bitCount_UInt4,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction findLSB_00D(BuiltInId::findLSB_Int1,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_10D(BuiltInId::findLSB_Int2,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_20D(BuiltInId::findLSB_Int3,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_30D(BuiltInId::findLSB_Int4,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_00E(BuiltInId::findLSB_UInt1,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_10E(BuiltInId::findLSB_UInt2,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_20E(BuiltInId::findLSB_UInt3,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_30E(BuiltInId::findLSB_UInt4,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findMSB_00D(BuiltInId::findMSB_Int1,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_10D(BuiltInId::findMSB_Int2,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_20D(BuiltInId::findMSB_Int3,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_30D(BuiltInId::findMSB_Int4,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_00E(BuiltInId::findMSB_UInt1,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_10E(BuiltInId::findMSB_UInt2,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_20E(BuiltInId::findMSB_UInt3,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_30E(BuiltInId::findMSB_UInt4,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction uaddCarry_00E00E00E(
+ BuiltInId::uaddCarry_UInt1_UInt1_UInt1,
+ BuiltInName::uaddCarry,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E_o_00E_o_00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUaddCarry,
+ false);
+constexpr const TFunction uaddCarry_10E10E10E(
+ BuiltInId::uaddCarry_UInt2_UInt2_UInt2,
+ BuiltInName::uaddCarry,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E_o_10E_o_10E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUaddCarry,
+ false);
+constexpr const TFunction uaddCarry_20E20E20E(
+ BuiltInId::uaddCarry_UInt3_UInt3_UInt3,
+ BuiltInName::uaddCarry,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E_o_20E_o_20E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpUaddCarry,
+ false);
+constexpr const TFunction uaddCarry_30E30E30E(
+ BuiltInId::uaddCarry_UInt4_UInt4_UInt4,
+ BuiltInName::uaddCarry,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E_o_30E_o_30E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpUaddCarry,
+ false);
+constexpr const TFunction usubBorrow_00E00E00E(
+ BuiltInId::usubBorrow_UInt1_UInt1_UInt1,
+ BuiltInName::usubBorrow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E_o_00E_o_00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUsubBorrow,
+ false);
+constexpr const TFunction usubBorrow_10E10E10E(
+ BuiltInId::usubBorrow_UInt2_UInt2_UInt2,
+ BuiltInName::usubBorrow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E_o_10E_o_10E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUsubBorrow,
+ false);
+constexpr const TFunction usubBorrow_20E20E20E(
+ BuiltInId::usubBorrow_UInt3_UInt3_UInt3,
+ BuiltInName::usubBorrow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E_o_20E_o_20E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpUsubBorrow,
+ false);
+constexpr const TFunction usubBorrow_30E30E30E(
+ BuiltInId::usubBorrow_UInt4_UInt4_UInt4,
+ BuiltInName::usubBorrow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E_o_30E_o_30E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpUsubBorrow,
+ false);
+constexpr const TFunction umulExtended_00E00E00E00E(
+ BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ BuiltInName::umulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E_o_00E_o_00E,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUmulExtended,
+ false);
+constexpr const TFunction umulExtended_10E10E10E10E(
+ BuiltInId::umulExtended_UInt2_UInt2_UInt2_UInt2,
+ BuiltInName::umulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E_o_10E_o_10E,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUmulExtended,
+ false);
+constexpr const TFunction umulExtended_20E20E20E20E(
+ BuiltInId::umulExtended_UInt3_UInt3_UInt3_UInt3,
+ BuiltInName::umulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E_o_20E_o_20E,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUmulExtended,
+ false);
+constexpr const TFunction umulExtended_30E30E30E30E(
+ BuiltInId::umulExtended_UInt4_UInt4_UInt4_UInt4,
+ BuiltInName::umulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E_o_30E_o_30E,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUmulExtended,
+ false);
+constexpr const TFunction imulExtended_00D00D00D00D(
+ BuiltInId::imulExtended_Int1_Int1_Int1_Int1,
+ BuiltInName::imulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D_o_00D_o_00D,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImulExtended,
+ false);
+constexpr const TFunction imulExtended_10D10D10D10D(
+ BuiltInId::imulExtended_Int2_Int2_Int2_Int2,
+ BuiltInName::imulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D_o_10D_o_10D,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImulExtended,
+ false);
+constexpr const TFunction imulExtended_20D20D20D20D(
+ BuiltInId::imulExtended_Int3_Int3_Int3_Int3,
+ BuiltInName::imulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D_o_20D_o_20D,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImulExtended,
+ false);
+constexpr const TFunction imulExtended_30D30D30D30D(
+ BuiltInId::imulExtended_Int4_Int4_Int4_Int4,
+ BuiltInName::imulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D_o_30D_o_30D,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImulExtended,
+ false);
+constexpr const TFunction texture2D_00I10B(
+ BuiltInId::texture2D_Sampler2D1_Float2,
+ BuiltInName::texture2D,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2D,
+ false);
+constexpr const TFunction texture2DProj_00I20B(
+ BuiltInId::texture2DProj_Sampler2D1_Float3,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProj,
+ false);
+constexpr const TFunction texture2DProj_00I30B(
+ BuiltInId::texture2DProj_Sampler2D1_Float4,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProj,
+ false);
+constexpr const TFunction textureCube_00K20B(
+ BuiltInId::textureCube_SamplerCube1_Float3,
+ BuiltInName::textureCube,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureCube,
+ false);
+constexpr const TFunction texture3D_00J20B(
+ BuiltInId::texture3D_Sampler3D1_Float3,
+ BuiltInName::texture3D,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J20B00B20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3D,
+ false);
+constexpr const TFunction texture3DProj_00J30B(
+ BuiltInId::texture3DProj_Sampler3D1_Float4,
+ BuiltInName::texture3DProj,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J30B00B20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3DProj,
+ false);
+constexpr const TFunction shadow2DEXT_00d20B(
+ BuiltInId::shadow2DEXT_Sampler2DShadow1_Float3,
+ BuiltInName::shadow2DEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shadow_samplers}},
+ BuiltInParameters::p00d20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpShadow2DEXT,
+ false);
+constexpr const TFunction shadow2DProjEXT_00d30B(
+ BuiltInId::shadow2DProjEXT_Sampler2DShadow1_Float4,
+ BuiltInName::shadow2DProjEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shadow_samplers}},
+ BuiltInParameters::p00d30B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpShadow2DProjEXT,
+ false);
+constexpr const TFunction texture2D_00M10B(
+ BuiltInId::texture2D_SamplerExternalOES1_Float2,
+ BuiltInName::texture2D,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_EGL_image_external, TExtension::NV_EGL_stream_consumer_external}},
+ BuiltInParameters::p00M10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2D,
+ false);
+constexpr const TFunction texture2DProj_00M20B(
+ BuiltInId::texture2DProj_SamplerExternalOES1_Float3,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_EGL_image_external, TExtension::NV_EGL_stream_consumer_external}},
+ BuiltInParameters::p00M20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProj,
+ false);
+constexpr const TFunction texture2DProj_00M30B(
+ BuiltInId::texture2DProj_SamplerExternalOES1_Float4,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_EGL_image_external, TExtension::NV_EGL_stream_consumer_external}},
+ BuiltInParameters::p00M30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProj,
+ false);
+constexpr const TFunction texture2DRect_00O10B(
+ BuiltInId::texture2DRect_Sampler2DRect1_Float2,
+ BuiltInName::texture2DRect,
+ std::array<TExtension, 1u>{{TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DRect,
+ false);
+constexpr const TFunction texture2DRectProj_00O20B(
+ BuiltInId::texture2DRectProj_Sampler2DRect1_Float3,
+ BuiltInName::texture2DRectProj,
+ std::array<TExtension, 1u>{{TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DRectProj,
+ false);
+constexpr const TFunction texture2DRectProj_00O30B(
+ BuiltInId::texture2DRectProj_Sampler2DRect1_Float4,
+ BuiltInName::texture2DRectProj,
+ std::array<TExtension, 1u>{{TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DRectProj,
+ false);
+constexpr const TFunction texture2DGradEXT_00I10B10B10B(
+ BuiltInId::texture2DGradEXT_Sampler2D1_Float2_Float2_Float2,
+ BuiltInName::texture2DGradEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I10B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DGradEXT,
+ false);
+constexpr const TFunction texture2DProjGradEXT_00I20B10B10B(
+ BuiltInId::texture2DProjGradEXT_Sampler2D1_Float3_Float2_Float2,
+ BuiltInName::texture2DProjGradEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I20B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjGradEXT,
+ false);
+constexpr const TFunction texture2DProjGradEXT_00I30B10B10B(
+ BuiltInId::texture2DProjGradEXT_Sampler2D1_Float4_Float2_Float2,
+ BuiltInName::texture2DProjGradEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I30B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjGradEXT,
+ false);
+constexpr const TFunction textureCubeGradEXT_00K20B20B20B(
+ BuiltInId::textureCubeGradEXT_SamplerCube1_Float3_Float3_Float3,
+ BuiltInName::textureCubeGradEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00K20B20B20B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureCubeGradEXT,
+ false);
+constexpr const TFunction textureVideoWEBGL_00y10B(
+ BuiltInId::textureVideoWEBGL_SamplerVideoWEBGL1_Float2,
+ BuiltInName::textureVideoWEBGL,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00y10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureVideoWEBGL,
+ false);
+constexpr const TFunction texture2D_00I10B00B(
+ BuiltInId::texture2D_Sampler2D1_Float2_Float1,
+ BuiltInName::texture2D,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DBias,
+ false);
+constexpr const TFunction texture2DProj_00I20B00B(
+ BuiltInId::texture2DProj_Sampler2D1_Float3_Float1,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjBias,
+ false);
+constexpr const TFunction texture2DProj_00I30B00B(
+ BuiltInId::texture2DProj_Sampler2D1_Float4_Float1,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjBias,
+ false);
+constexpr const TFunction textureCube_00K20B00B(
+ BuiltInId::textureCube_SamplerCube1_Float3_Float1,
+ BuiltInName::textureCube,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureCubeBias,
+ false);
+constexpr const TFunction texture3D_00J20B00B(
+ BuiltInId::texture3D_Sampler3D1_Float3_Float1,
+ BuiltInName::texture3D,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J20B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3DBias,
+ false);
+constexpr const TFunction texture3DProj_00J30B00B(
+ BuiltInId::texture3DProj_Sampler3D1_Float4_Float1,
+ BuiltInName::texture3DProj,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J30B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3DProjBias,
+ false);
+constexpr const TFunction texture3DLod_00J20B00B(
+ BuiltInId::texture3DLod_Sampler3D1_Float3_Float1,
+ BuiltInName::texture3DLod,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J20B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3DLod,
+ false);
+constexpr const TFunction texture3DProjLod_00J30B00B(
+ BuiltInId::texture3DProjLod_Sampler3D1_Float4_Float1,
+ BuiltInName::texture3DProjLod,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J30B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3DProjLod,
+ false);
+constexpr const TFunction texture2DLod_00I10B00B(
+ BuiltInId::texture2DLod_Sampler2D1_Float2_Float1,
+ BuiltInName::texture2DLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DLodVS,
+ false);
+constexpr const TFunction texture2DProjLod_00I20B00B(
+ BuiltInId::texture2DProjLod_Sampler2D1_Float3_Float1,
+ BuiltInName::texture2DProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjLodVS,
+ false);
+constexpr const TFunction texture2DProjLod_00I30B00B(
+ BuiltInId::texture2DProjLod_Sampler2D1_Float4_Float1,
+ BuiltInName::texture2DProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjLodVS,
+ false);
+constexpr const TFunction textureCubeLod_00K20B00B(
+ BuiltInId::textureCubeLod_SamplerCube1_Float3_Float1,
+ BuiltInName::textureCubeLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureCubeLodVS,
+ false);
+constexpr const TFunction texture2DLodEXT_00I10B00B(
+ BuiltInId::texture2DLodEXT_Sampler2D1_Float2_Float1,
+ BuiltInName::texture2DLodEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I10B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DLodEXTFS,
+ false);
+constexpr const TFunction texture2DProjLodEXT_00I20B00B(
+ BuiltInId::texture2DProjLodEXT_Sampler2D1_Float3_Float1,
+ BuiltInName::texture2DProjLodEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjLodEXTFS,
+ false);
+constexpr const TFunction texture2DProjLodEXT_00I30B00B(
+ BuiltInId::texture2DProjLodEXT_Sampler2D1_Float4_Float1,
+ BuiltInName::texture2DProjLodEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjLodEXTFS,
+ false);
+constexpr const TFunction textureCubeLodEXT_00K20B00B(
+ BuiltInId::textureCubeLodEXT_SamplerCube1_Float3_Float1,
+ BuiltInName::textureCubeLodEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00K20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureCubeLodEXTFS,
+ false);
+constexpr const TFunction texture_00I10B(BuiltInId::texture_Sampler2D1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00R10B(BuiltInId::texture_ISampler2D1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00X10B(BuiltInId::texture_USampler2D1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00J20B(BuiltInId::texture_Sampler3D1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B00B20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00S20B(BuiltInId::texture_ISampler3D1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B00B20D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00Y20B(BuiltInId::texture_USampler3D1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B00B20D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00K20B(BuiltInId::texture_SamplerCube1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00T20B(BuiltInId::texture_ISamplerCube1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00Z20B(BuiltInId::texture_USamplerCube1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00L20B(BuiltInId::texture_Sampler2DArray1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00U20B(BuiltInId::texture_ISampler2DArray1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00a20B(BuiltInId::texture_USampler2DArray1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00d20B(BuiltInId::texture_Sampler2DShadow1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00e30B(BuiltInId::texture_SamplerCubeShadow1_Float4,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00f30B(BuiltInId::texture_Sampler2DArrayShadow1_Float4,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f30B10B10B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00k30B(BuiltInId::texture_SamplerCubeArray1_Float4,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00s30B(BuiltInId::texture_ISamplerCubeArray1_Float4,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00x30B(BuiltInId::texture_USamplerCubeArray1_Float4,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00l30B00B(
+ BuiltInId::texture_SamplerCubeArrayShadow1_Float4_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00l30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction textureExt_00k30B(
+ BuiltInId::textureExt_SamplerCubeArray1_Float4,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction textureExt_00s30B(
+ BuiltInId::textureExt_ISamplerCubeArray1_Float4,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction textureExt_00x30B(
+ BuiltInId::textureExt_USamplerCubeArray1_Float4,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction textureExt_00l30B00B(
+ BuiltInId::textureExt_SamplerCubeArrayShadow1_Float4_Float1,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00l30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00M10B(BuiltInId::texture_SamplerExternalOES1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00N10B(BuiltInId::texture_SamplerExternal2DY2YEXT1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00O10B(BuiltInId::texture_Sampler2DRect1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{
+ {TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00y10B(BuiltInId::texture_SamplerVideoWEBGL1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00y10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction textureProj_00I20B(
+ BuiltInId::textureProj_Sampler2D1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00R20B(
+ BuiltInId::textureProj_ISampler2D1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00X20B(
+ BuiltInId::textureProj_USampler2D1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00I30B(
+ BuiltInId::textureProj_Sampler2D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00R30B(
+ BuiltInId::textureProj_ISampler2D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00X30B(
+ BuiltInId::textureProj_USampler2D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00J30B(
+ BuiltInId::textureProj_Sampler3D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B00B20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00S30B(
+ BuiltInId::textureProj_ISampler3D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B00B20D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00Y30B(
+ BuiltInId::textureProj_USampler3D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B00B20D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00d30B(
+ BuiltInId::textureProj_Sampler2DShadow1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00M20B(
+ BuiltInId::textureProj_SamplerExternalOES1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00M30B(
+ BuiltInId::textureProj_SamplerExternalOES1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00N20B(
+ BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00N30B(
+ BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00O20B(
+ BuiltInId::textureProj_Sampler2DRect1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00O30B(
+ BuiltInId::textureProj_Sampler2DRect1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureLod_00I10B00B(
+ BuiltInId::textureLod_Sampler2D1_Float2_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00R10B00B(
+ BuiltInId::textureLod_ISampler2D1_Float2_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00X10B00B(
+ BuiltInId::textureLod_USampler2D1_Float2_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00J20B00B(
+ BuiltInId::textureLod_Sampler3D1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00S20B00B(
+ BuiltInId::textureLod_ISampler3D1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B00B20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00Y20B00B(
+ BuiltInId::textureLod_USampler3D1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B00B20D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00K20B00B(
+ BuiltInId::textureLod_SamplerCube1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00T20B00B(
+ BuiltInId::textureLod_ISamplerCube1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00Z20B00B(
+ BuiltInId::textureLod_USamplerCube1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00L20B00B(
+ BuiltInId::textureLod_Sampler2DArray1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00U20B00B(
+ BuiltInId::textureLod_ISampler2DArray1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00a20B00B(
+ BuiltInId::textureLod_USampler2DArray1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00d20B00B(
+ BuiltInId::textureLod_Sampler2DShadow1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00k30B00B(
+ BuiltInId::textureLod_SamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00s30B00B(
+ BuiltInId::textureLod_ISamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00x30B00B(
+ BuiltInId::textureLod_USamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLodExt_00k30B00B(
+ BuiltInId::textureLodExt_SamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLodExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLodExt_00s30B00B(
+ BuiltInId::textureLodExt_ISamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLodExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLodExt_00x30B00B(
+ BuiltInId::textureLodExt_USamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLodExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureSize_00I00D(
+ BuiltInId::textureSize_Sampler2D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00R00D(
+ BuiltInId::textureSize_ISampler2D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00X00D(
+ BuiltInId::textureSize_USampler2D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00J00D(
+ BuiltInId::textureSize_Sampler3D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00S00D(
+ BuiltInId::textureSize_ISampler3D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00Y00D(
+ BuiltInId::textureSize_USampler3D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00K00D(
+ BuiltInId::textureSize_SamplerCube1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00T00D(
+ BuiltInId::textureSize_ISamplerCube1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00Z00D(
+ BuiltInId::textureSize_USamplerCube1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00L00D(
+ BuiltInId::textureSize_Sampler2DArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00U00D(
+ BuiltInId::textureSize_ISampler2DArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00a00D(
+ BuiltInId::textureSize_USampler2DArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00d00D(
+ BuiltInId::textureSize_Sampler2DShadow1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00e00D(
+ BuiltInId::textureSize_SamplerCubeShadow1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00f00D(
+ BuiltInId::textureSize_Sampler2DArrayShadow1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00k00D(
+ BuiltInId::textureSize_SamplerCubeArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00s00D(
+ BuiltInId::textureSize_ISamplerCubeArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00x00D(
+ BuiltInId::textureSize_USamplerCubeArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00l00D(
+ BuiltInId::textureSize_SamplerCubeArrayShadow1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00l00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00k00D(
+ BuiltInId::textureSizeExt_SamplerCubeArray1_Int1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00s00D(
+ BuiltInId::textureSizeExt_ISamplerCubeArray1_Int1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00x00D(
+ BuiltInId::textureSizeExt_USamplerCubeArray1_Int1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00l00D(
+ BuiltInId::textureSizeExt_SamplerCubeArrayShadow1_Int1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00l00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00j(BuiltInId::textureSize_SamplerBuffer1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00j00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00r(BuiltInId::textureSize_ISamplerBuffer1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00r00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00w(BuiltInId::textureSize_USamplerBuffer1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00w00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00j(
+ BuiltInId::textureSizeExt_SamplerBuffer1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00j00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00r(
+ BuiltInId::textureSizeExt_ISamplerBuffer1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00r00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00w(
+ BuiltInId::textureSizeExt_USamplerBuffer1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00w00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00P(BuiltInId::textureSize_Sampler2DMS1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00P10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00V(BuiltInId::textureSize_ISampler2DMS1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00V10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00b(BuiltInId::textureSize_USampler2DMS1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00b10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00P(
+ BuiltInId::textureSizeExt_Sampler2DMS1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00P10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00V(
+ BuiltInId::textureSizeExt_ISampler2DMS1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00V10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00b(
+ BuiltInId::textureSizeExt_USampler2DMS1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00b10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00Q(BuiltInId::textureSize_Sampler2DMSArray1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Q20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00W(BuiltInId::textureSize_ISampler2DMSArray1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00W20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00c(BuiltInId::textureSize_USampler2DMSArray1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00c20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00Q(
+ BuiltInId::textureSizeExt_Sampler2DMSArray1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00Q20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00W(
+ BuiltInId::textureSizeExt_ISampler2DMSArray1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00W20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00c(
+ BuiltInId::textureSizeExt_USampler2DMSArray1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00c20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00M00D(
+ BuiltInId::textureSize_SamplerExternalOES1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00N00D(
+ BuiltInId::textureSize_SamplerExternal2DY2YEXT1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureProjLod_00I20B00B(
+ BuiltInId::textureProjLod_Sampler2D1_Float3_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00R20B00B(
+ BuiltInId::textureProjLod_ISampler2D1_Float3_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00X20B00B(
+ BuiltInId::textureProjLod_USampler2D1_Float3_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00I30B00B(
+ BuiltInId::textureProjLod_Sampler2D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00R30B00B(
+ BuiltInId::textureProjLod_ISampler2D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00X30B00B(
+ BuiltInId::textureProjLod_USampler2D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00J30B00B(
+ BuiltInId::textureProjLod_Sampler3D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00S30B00B(
+ BuiltInId::textureProjLod_ISampler3D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B00B20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00Y30B00B(
+ BuiltInId::textureProjLod_USampler3D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B00B20D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00d30B00B(
+ BuiltInId::textureProjLod_Sampler2DShadow1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction texelFetch_00I10D00D(
+ BuiltInId::texelFetch_Sampler2D1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10D00D10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00R10D00D(
+ BuiltInId::texelFetch_ISampler2D1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10D00D10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00X10D00D(
+ BuiltInId::texelFetch_USampler2D1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10D00D10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00J20D00D(
+ BuiltInId::texelFetch_Sampler3D1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20D00D20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00S20D00D(
+ BuiltInId::texelFetch_ISampler3D1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20D00D20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00Y20D00D(
+ BuiltInId::texelFetch_USampler3D1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20D00D20D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00L20D00D(
+ BuiltInId::texelFetch_Sampler2DArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20D00D10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00U20D00D(
+ BuiltInId::texelFetch_ISampler2DArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20D00D10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00a20D00D(
+ BuiltInId::texelFetch_USampler2DArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20D00D10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00j00D(
+ BuiltInId::texelFetch_SamplerBuffer1_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00j00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00r00D(
+ BuiltInId::texelFetch_ISamplerBuffer1_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00r00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00w00D(
+ BuiltInId::texelFetch_USamplerBuffer1_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00w00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00j00D(
+ BuiltInId::texelFetchExt_SamplerBuffer1_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00j00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00r00D(
+ BuiltInId::texelFetchExt_ISamplerBuffer1_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00r00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00w00D(
+ BuiltInId::texelFetchExt_USamplerBuffer1_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00w00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00P10D00D(
+ BuiltInId::texelFetch_Sampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00P10D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00V10D00D(
+ BuiltInId::texelFetch_ISampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00V10D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00b10D00D(
+ BuiltInId::texelFetch_USampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00b10D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00P10D00D(
+ BuiltInId::texelFetchExt_Sampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00P10D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00V10D00D(
+ BuiltInId::texelFetchExt_ISampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00V10D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00b10D00D(
+ BuiltInId::texelFetchExt_USampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00b10D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00Q20D00D(
+ BuiltInId::texelFetch_Sampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Q20D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00W20D00D(
+ BuiltInId::texelFetch_ISampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00W20D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00c20D00D(
+ BuiltInId::texelFetch_USampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00c20D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00Q20D00D(
+ BuiltInId::texelFetchExt_Sampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00Q20D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00W20D00D(
+ BuiltInId::texelFetchExt_ISampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00W20D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00c20D00D(
+ BuiltInId::texelFetchExt_USampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00c20D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00M10D00D(
+ BuiltInId::texelFetch_SamplerExternalOES1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M10D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00N10D00D(
+ BuiltInId::texelFetch_SamplerExternal2DY2YEXT1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N10D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction textureGrad_00I10B10B10B(
+ BuiltInId::textureGrad_Sampler2D1_Float2_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00R10B10B10B(
+ BuiltInId::textureGrad_ISampler2D1_Float2_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10B10B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00X10B10B10B(
+ BuiltInId::textureGrad_USampler2D1_Float2_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10B10B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00J20B20B20B(
+ BuiltInId::textureGrad_Sampler3D1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B20B20B20D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00S20B20B20B(
+ BuiltInId::textureGrad_ISampler3D1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B20B20B20D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00Y20B20B20B(
+ BuiltInId::textureGrad_USampler3D1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B20B20B20D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00K20B20B20B(
+ BuiltInId::textureGrad_SamplerCube1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B20B20B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00T20B20B20B(
+ BuiltInId::textureGrad_ISamplerCube1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B20B20B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00Z20B20B20B(
+ BuiltInId::textureGrad_USamplerCube1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B20B20B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00d20B10B10B(
+ BuiltInId::textureGrad_Sampler2DShadow1_Float3_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00e30B20B20B(
+ BuiltInId::textureGrad_SamplerCubeShadow1_Float4_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e30B20B20B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00L20B10B10B(
+ BuiltInId::textureGrad_Sampler2DArray1_Float3_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00U20B10B10B(
+ BuiltInId::textureGrad_ISampler2DArray1_Float3_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10B10B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00a20B10B10B(
+ BuiltInId::textureGrad_USampler2DArray1_Float3_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10B10B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00f30B10B10B(
+ BuiltInId::textureGrad_Sampler2DArrayShadow1_Float4_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f30B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00k30B20B20B(
+ BuiltInId::textureGrad_SamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B20B20B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00s30B20B20B(
+ BuiltInId::textureGrad_ISamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B20B20B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00x30B20B20B(
+ BuiltInId::textureGrad_USamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B20B20B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGradExt_00k30B20B20B(
+ BuiltInId::textureGradExt_SamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGradExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B20B20B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGradExt_00s30B20B20B(
+ BuiltInId::textureGradExt_ISamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGradExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B20B20B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGradExt_00x30B20B20B(
+ BuiltInId::textureGradExt_USamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGradExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B20B20B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureProjGrad_00I20B10B10B(
+ BuiltInId::textureProjGrad_Sampler2D1_Float3_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00R20B10B10B(
+ BuiltInId::textureProjGrad_ISampler2D1_Float3_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B10B10B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00X20B10B10B(
+ BuiltInId::textureProjGrad_USampler2D1_Float3_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B10B10B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00I30B10B10B(
+ BuiltInId::textureProjGrad_Sampler2D1_Float4_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00R30B10B10B(
+ BuiltInId::textureProjGrad_ISampler2D1_Float4_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B10B10B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00X30B10B10B(
+ BuiltInId::textureProjGrad_USampler2D1_Float4_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B10B10B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00J30B20B20B(
+ BuiltInId::textureProjGrad_Sampler3D1_Float4_Float3_Float3,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B20B20B20D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00S30B20B20B(
+ BuiltInId::textureProjGrad_ISampler3D1_Float4_Float3_Float3,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B20B20B20D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00Y30B20B20B(
+ BuiltInId::textureProjGrad_USampler3D1_Float4_Float3_Float3,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B20B20B20D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00d30B10B10B(
+ BuiltInId::textureProjGrad_Sampler2DShadow1_Float4_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction texture_00I10B00B(
+ BuiltInId::texture_Sampler2D1_Float2_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00R10B00B(
+ BuiltInId::texture_ISampler2D1_Float2_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00X10B00B(
+ BuiltInId::texture_USampler2D1_Float2_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00J20B00B(
+ BuiltInId::texture_Sampler3D1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00S20B00B(
+ BuiltInId::texture_ISampler3D1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B00B20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00Y20B00B(
+ BuiltInId::texture_USampler3D1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B00B20D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00K20B00B(
+ BuiltInId::texture_SamplerCube1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00T20B00B(
+ BuiltInId::texture_ISamplerCube1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00Z20B00B(
+ BuiltInId::texture_USamplerCube1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00L20B00B(
+ BuiltInId::texture_Sampler2DArray1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00U20B00B(
+ BuiltInId::texture_ISampler2DArray1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00a20B00B(
+ BuiltInId::texture_USampler2DArray1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureProj_00I20B00B(
+ BuiltInId::textureProj_Sampler2D1_Float3_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00R20B00B(
+ BuiltInId::textureProj_ISampler2D1_Float3_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00X20B00B(
+ BuiltInId::textureProj_USampler2D1_Float3_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00I30B00B(
+ BuiltInId::textureProj_Sampler2D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00R30B00B(
+ BuiltInId::textureProj_ISampler2D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00X30B00B(
+ BuiltInId::textureProj_USampler2D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00J30B00B(
+ BuiltInId::textureProj_Sampler3D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00S30B00B(
+ BuiltInId::textureProj_ISampler3D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B00B20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00Y30B00B(
+ BuiltInId::textureProj_USampler3D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B00B20D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction texture_00d20B00B(
+ BuiltInId::texture_Sampler2DShadow1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00e30B00B(
+ BuiltInId::texture_SamplerCubeShadow1_Float4_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureProj_00d30B00B(
+ BuiltInId::textureProj_Sampler2DShadow1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction texture_00k30B00B(
+ BuiltInId::texture_SamplerCubeArray1_Float4_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00s30B00B(
+ BuiltInId::texture_ISamplerCubeArray1_Float4_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00x30B00B(
+ BuiltInId::texture_USamplerCubeArray1_Float4_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureExt_00k30B00B(
+ BuiltInId::textureExt_SamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureExt_00s30B00B(
+ BuiltInId::textureExt_ISamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureExt_00x30B00B(
+ BuiltInId::textureExt_USamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00M10B00B(
+ BuiltInId::texture_SamplerExternalOES1_Float2_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M10B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureProj_00M20B00B(
+ BuiltInId::textureProj_SamplerExternalOES1_Float3_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00M30B00B(
+ BuiltInId::textureProj_SamplerExternalOES1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction texture_00N10B00B(
+ BuiltInId::texture_SamplerExternal2DY2YEXT1_Float2_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N10B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureProj_00N20B00B(
+ BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float3_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00N30B00B(
+ BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureOffset_00I10B10D(
+ BuiltInId::textureOffset_Sampler2D1_Float2_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00R10B10D(
+ BuiltInId::textureOffset_ISampler2D1_Float2_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00X10B10D(
+ BuiltInId::textureOffset_USampler2D1_Float2_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00J20B20D(
+ BuiltInId::textureOffset_Sampler3D1_Float3_Int3,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B20D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00S20B20D(
+ BuiltInId::textureOffset_ISampler3D1_Float3_Int3,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00Y20B20D(
+ BuiltInId::textureOffset_USampler3D1_Float3_Int3,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B20D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00d20B10D(
+ BuiltInId::textureOffset_Sampler2DShadow1_Float3_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00L20B10D(
+ BuiltInId::textureOffset_Sampler2DArray1_Float3_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00U20B10D(
+ BuiltInId::textureOffset_ISampler2DArray1_Float3_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00a20B10D(
+ BuiltInId::textureOffset_USampler2DArray1_Float3_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureProjOffset_00I20B10D(
+ BuiltInId::textureProjOffset_Sampler2D1_Float3_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00R20B10D(
+ BuiltInId::textureProjOffset_ISampler2D1_Float3_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00X20B10D(
+ BuiltInId::textureProjOffset_USampler2D1_Float3_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00I30B10D(
+ BuiltInId::textureProjOffset_Sampler2D1_Float4_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00R30B10D(
+ BuiltInId::textureProjOffset_ISampler2D1_Float4_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00X30B10D(
+ BuiltInId::textureProjOffset_USampler2D1_Float4_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00J30B20D(
+ BuiltInId::textureProjOffset_Sampler3D1_Float4_Int3,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B20D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00S30B20D(
+ BuiltInId::textureProjOffset_ISampler3D1_Float4_Int3,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00Y30B20D(
+ BuiltInId::textureProjOffset_USampler3D1_Float4_Int3,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B20D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00d30B10D(
+ BuiltInId::textureProjOffset_Sampler2DShadow1_Float4_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureLodOffset_00I10B00B10D(
+ BuiltInId::textureLodOffset_Sampler2D1_Float2_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00R10B00B10D(
+ BuiltInId::textureLodOffset_ISampler2D1_Float2_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00X10B00B10D(
+ BuiltInId::textureLodOffset_USampler2D1_Float2_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00J20B00B20D(
+ BuiltInId::textureLodOffset_Sampler3D1_Float3_Float1_Int3,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B00B20D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00S20B00B20D(
+ BuiltInId::textureLodOffset_ISampler3D1_Float3_Float1_Int3,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B00B20D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00Y20B00B20D(
+ BuiltInId::textureLodOffset_USampler3D1_Float3_Float1_Int3,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B00B20D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00d20B00B10D(
+ BuiltInId::textureLodOffset_Sampler2DShadow1_Float3_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00L20B00B10D(
+ BuiltInId::textureLodOffset_Sampler2DArray1_Float3_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00U20B00B10D(
+ BuiltInId::textureLodOffset_ISampler2DArray1_Float3_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00a20B00B10D(
+ BuiltInId::textureLodOffset_USampler2DArray1_Float3_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00I20B00B10D(
+ BuiltInId::textureProjLodOffset_Sampler2D1_Float3_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00R20B00B10D(
+ BuiltInId::textureProjLodOffset_ISampler2D1_Float3_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B00B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00X20B00B10D(
+ BuiltInId::textureProjLodOffset_USampler2D1_Float3_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B00B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00I30B00B10D(
+ BuiltInId::textureProjLodOffset_Sampler2D1_Float4_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00R30B00B10D(
+ BuiltInId::textureProjLodOffset_ISampler2D1_Float4_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B00B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00X30B00B10D(
+ BuiltInId::textureProjLodOffset_USampler2D1_Float4_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B00B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00J30B00B20D(
+ BuiltInId::textureProjLodOffset_Sampler3D1_Float4_Float1_Int3,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B00B20D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00S30B00B20D(
+ BuiltInId::textureProjLodOffset_ISampler3D1_Float4_Float1_Int3,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B00B20D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00Y30B00B20D(
+ BuiltInId::textureProjLodOffset_USampler3D1_Float4_Float1_Int3,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B00B20D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00d30B00B10D(
+ BuiltInId::textureProjLodOffset_Sampler2DShadow1_Float4_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00I10D00D10D(
+ BuiltInId::texelFetchOffset_Sampler2D1_Int2_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10D00D10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00R10D00D10D(
+ BuiltInId::texelFetchOffset_ISampler2D1_Int2_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10D00D10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00X10D00D10D(
+ BuiltInId::texelFetchOffset_USampler2D1_Int2_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10D00D10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00J20D00D20D(
+ BuiltInId::texelFetchOffset_Sampler3D1_Int3_Int1_Int3,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20D00D20D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00S20D00D20D(
+ BuiltInId::texelFetchOffset_ISampler3D1_Int3_Int1_Int3,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20D00D20D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00Y20D00D20D(
+ BuiltInId::texelFetchOffset_USampler3D1_Int3_Int1_Int3,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20D00D20D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00L20D00D10D(
+ BuiltInId::texelFetchOffset_Sampler2DArray1_Int3_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20D00D10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00U20D00D10D(
+ BuiltInId::texelFetchOffset_ISampler2DArray1_Int3_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20D00D10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00a20D00D10D(
+ BuiltInId::texelFetchOffset_USampler2DArray1_Int3_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20D00D10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction textureGradOffset_00I10B10B10B10D(
+ BuiltInId::textureGradOffset_Sampler2D1_Float2_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00R10B10B10B10D(
+ BuiltInId::textureGradOffset_ISampler2D1_Float2_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10B10B10D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00X10B10B10B10D(
+ BuiltInId::textureGradOffset_USampler2D1_Float2_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10B10B10D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00J20B20B20B20D(
+ BuiltInId::textureGradOffset_Sampler3D1_Float3_Float3_Float3_Int3,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B20B20B20D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00S20B20B20B20D(
+ BuiltInId::textureGradOffset_ISampler3D1_Float3_Float3_Float3_Int3,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B20B20B20D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00Y20B20B20B20D(
+ BuiltInId::textureGradOffset_USampler3D1_Float3_Float3_Float3_Int3,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B20B20B20D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00d20B10B10B10D(
+ BuiltInId::textureGradOffset_Sampler2DShadow1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00L20B10B10B10D(
+ BuiltInId::textureGradOffset_Sampler2DArray1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00U20B10B10B10D(
+ BuiltInId::textureGradOffset_ISampler2DArray1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10B10B10D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00a20B10B10B10D(
+ BuiltInId::textureGradOffset_USampler2DArray1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10B10B10D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00f30B10B10B10D(
+ BuiltInId::textureGradOffset_Sampler2DArrayShadow1_Float4_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f30B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00I20B10B10B10D(
+ BuiltInId::textureProjGradOffset_Sampler2D1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00R20B10B10B10D(
+ BuiltInId::textureProjGradOffset_ISampler2D1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B10B10B10D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00X20B10B10B10D(
+ BuiltInId::textureProjGradOffset_USampler2D1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B10B10B10D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00I30B10B10B10D(
+ BuiltInId::textureProjGradOffset_Sampler2D1_Float4_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00R30B10B10B10D(
+ BuiltInId::textureProjGradOffset_ISampler2D1_Float4_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B10B10B10D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00X30B10B10B10D(
+ BuiltInId::textureProjGradOffset_USampler2D1_Float4_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B10B10B10D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00J30B20B20B20D(
+ BuiltInId::textureProjGradOffset_Sampler3D1_Float4_Float3_Float3_Int3,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B20B20B20D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00S30B20B20B20D(
+ BuiltInId::textureProjGradOffset_ISampler3D1_Float4_Float3_Float3_Int3,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B20B20B20D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00Y30B20B20B20D(
+ BuiltInId::textureProjGradOffset_USampler3D1_Float4_Float3_Float3_Int3,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B20B20B20D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00d30B10B10B10D(
+ BuiltInId::textureProjGradOffset_Sampler2DShadow1_Float4_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureOffset_00I10B10D00B(
+ BuiltInId::textureOffset_Sampler2D1_Float2_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00R10B10D00B(
+ BuiltInId::textureOffset_ISampler2D1_Float2_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00X10B10D00B(
+ BuiltInId::textureOffset_USampler2D1_Float2_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00J20B20D00B(
+ BuiltInId::textureOffset_Sampler3D1_Float3_Int3_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B20D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00S20B20D00B(
+ BuiltInId::textureOffset_ISampler3D1_Float3_Int3_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B20D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00Y20B20D00B(
+ BuiltInId::textureOffset_USampler3D1_Float3_Int3_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B20D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00d20B10D00B(
+ BuiltInId::textureOffset_Sampler2DShadow1_Float3_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00L20B10D00B(
+ BuiltInId::textureOffset_Sampler2DArray1_Float3_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00U20B10D00B(
+ BuiltInId::textureOffset_ISampler2DArray1_Float3_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00a20B10D00B(
+ BuiltInId::textureOffset_USampler2DArray1_Float3_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00I20B10D00B(
+ BuiltInId::textureProjOffset_Sampler2D1_Float3_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00R20B10D00B(
+ BuiltInId::textureProjOffset_ISampler2D1_Float3_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B10D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00X20B10D00B(
+ BuiltInId::textureProjOffset_USampler2D1_Float3_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B10D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00I30B10D00B(
+ BuiltInId::textureProjOffset_Sampler2D1_Float4_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00R30B10D00B(
+ BuiltInId::textureProjOffset_ISampler2D1_Float4_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B10D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00X30B10D00B(
+ BuiltInId::textureProjOffset_USampler2D1_Float4_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B10D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00J30B20D00B(
+ BuiltInId::textureProjOffset_Sampler3D1_Float4_Int3_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B20D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00S30B20D00B(
+ BuiltInId::textureProjOffset_ISampler3D1_Float4_Int3_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B20D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00Y30B20D00B(
+ BuiltInId::textureProjOffset_USampler3D1_Float4_Int3_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B20D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00d30B10D00B(
+ BuiltInId::textureProjOffset_Sampler2DShadow1_Float4_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureGather_00I10B(
+ BuiltInId::textureGather_Sampler2D1_Float2,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00R10B(
+ BuiltInId::textureGather_ISampler2D1_Float2,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00X10B(
+ BuiltInId::textureGather_USampler2D1_Float2,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00I10B00D(
+ BuiltInId::textureGather_Sampler2D1_Float2_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00R10B00D(
+ BuiltInId::textureGather_ISampler2D1_Float2_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00X10B00D(
+ BuiltInId::textureGather_USampler2D1_Float2_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00L20B(
+ BuiltInId::textureGather_Sampler2DArray1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00U20B(
+ BuiltInId::textureGather_ISampler2DArray1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00a20B(
+ BuiltInId::textureGather_USampler2DArray1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00L20B00D(
+ BuiltInId::textureGather_Sampler2DArray1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00U20B00D(
+ BuiltInId::textureGather_ISampler2DArray1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00a20B00D(
+ BuiltInId::textureGather_USampler2DArray1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00K20B(
+ BuiltInId::textureGather_SamplerCube1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00T20B(
+ BuiltInId::textureGather_ISamplerCube1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00Z20B(
+ BuiltInId::textureGather_USamplerCube1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00K20B00D(
+ BuiltInId::textureGather_SamplerCube1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00T20B00D(
+ BuiltInId::textureGather_ISamplerCube1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00Z20B00D(
+ BuiltInId::textureGather_USamplerCube1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00k30B(
+ BuiltInId::textureGather_SamplerCubeArray1_Float4,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00s30B(
+ BuiltInId::textureGather_ISamplerCubeArray1_Float4,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00x30B(
+ BuiltInId::textureGather_USamplerCubeArray1_Float4,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00k30B00D(
+ BuiltInId::textureGather_SamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00s30B00D(
+ BuiltInId::textureGather_ISamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00x30B00D(
+ BuiltInId::textureGather_USamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00l30B00B(
+ BuiltInId::textureGather_SamplerCubeArrayShadow1_Float4_Float1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00l30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00k30B(
+ BuiltInId::textureGatherExt_SamplerCubeArray1_Float4,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00s30B(
+ BuiltInId::textureGatherExt_ISamplerCubeArray1_Float4,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00x30B(
+ BuiltInId::textureGatherExt_USamplerCubeArray1_Float4,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00k30B00D(
+ BuiltInId::textureGatherExt_SamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00s30B00D(
+ BuiltInId::textureGatherExt_ISamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00x30B00D(
+ BuiltInId::textureGatherExt_USamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00l30B00B(
+ BuiltInId::textureGatherExt_SamplerCubeArrayShadow1_Float4_Float1,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00l30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00d10B(
+ BuiltInId::textureGather_Sampler2DShadow1_Float2,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d10B00B10Dx4,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00d10B00B(
+ BuiltInId::textureGather_Sampler2DShadow1_Float2_Float1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d10B00B10Dx4,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00f20B(
+ BuiltInId::textureGather_Sampler2DArrayShadow1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f20B00B10Dx4,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00f20B00B(
+ BuiltInId::textureGather_Sampler2DArrayShadow1_Float3_Float1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f20B00B10Dx4,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00e20B(
+ BuiltInId::textureGather_SamplerCubeShadow1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00e20B00B(
+ BuiltInId::textureGather_SamplerCubeShadow1_Float3_Float1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherOffset_00I10B10D(
+ BuiltInId::textureGatherOffset_Sampler2D1_Float2_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00R10B10D(
+ BuiltInId::textureGatherOffset_ISampler2D1_Float2_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00X10B10D(
+ BuiltInId::textureGatherOffset_USampler2D1_Float2_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00L20B10D(
+ BuiltInId::textureGatherOffset_Sampler2DArray1_Float3_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00U20B10D(
+ BuiltInId::textureGatherOffset_ISampler2DArray1_Float3_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00a20B10D(
+ BuiltInId::textureGatherOffset_USampler2DArray1_Float3_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00d10B00B10D(
+ BuiltInId::textureGatherOffset_Sampler2DShadow1_Float2_Float1_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d10B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00f20B00B10D(
+ BuiltInId::textureGatherOffset_Sampler2DArrayShadow1_Float3_Float1_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f20B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00I10B10D00D(
+ BuiltInId::textureGatherOffset_Sampler2D1_Float2_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10D00D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffset_00R10B10D00D(
+ BuiltInId::textureGatherOffset_ISampler2D1_Float2_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffset_00X10B10D00D(
+ BuiltInId::textureGatherOffset_USampler2D1_Float2_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffset_00L20B10D00D(
+ BuiltInId::textureGatherOffset_Sampler2DArray1_Float3_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10D00D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffset_00U20B10D00D(
+ BuiltInId::textureGatherOffset_ISampler2DArray1_Float3_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffset_00a20B10D00D(
+ BuiltInId::textureGatherOffset_USampler2DArray1_Float3_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00I10B10Dx4(
+ BuiltInId::textureGatherOffsets_Sampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10Dx400D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00R10B10Dx4(
+ BuiltInId::textureGatherOffsets_ISampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10Dx400D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00X10B10Dx4(
+ BuiltInId::textureGatherOffsets_USampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10Dx400D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00L20B10Dx4(
+ BuiltInId::textureGatherOffsets_Sampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10Dx400D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00U20B10Dx4(
+ BuiltInId::textureGatherOffsets_ISampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10Dx400D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00a20B10Dx4(
+ BuiltInId::textureGatherOffsets_USampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10Dx400D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00d10B00B10Dx4(
+ BuiltInId::textureGatherOffsets_Sampler2DShadow1_Float2_Float1_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d10B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00f20B00B10Dx4(
+ BuiltInId::textureGatherOffsets_Sampler2DArrayShadow1_Float3_Float1_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f20B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00I10B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00I10B10Dx400D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00R10B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00R10B10Dx400D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00X10B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_USampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00X10B10Dx400D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00L20B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00L20B10Dx400D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00U20B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00U20B10Dx400D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00a20B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00a20B10Dx400D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00d10B00B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_Sampler2DShadow1_Float2_Float1_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00d10B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00f20B00B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_Sampler2DArrayShadow1_Float3_Float1_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00f20B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00I10B10Dx400D(
+ BuiltInId::textureGatherOffsets_Sampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10Dx400D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00R10B10Dx400D(
+ BuiltInId::textureGatherOffsets_ISampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10Dx400D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00X10B10Dx400D(
+ BuiltInId::textureGatherOffsets_USampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10Dx400D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00L20B10Dx400D(
+ BuiltInId::textureGatherOffsets_Sampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10Dx400D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00U20B10Dx400D(
+ BuiltInId::textureGatherOffsets_ISampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10Dx400D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00a20B10Dx400D(
+ BuiltInId::textureGatherOffsets_USampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10Dx400D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00I10B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00I10B10Dx400D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00R10B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00R10B10Dx400D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00X10B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_USampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00X10B10Dx400D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00L20B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00L20B10Dx400D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00U20B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00U20B10Dx400D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00a20B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00a20B10Dx400D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction rgb_2_yuv_20B00H(
+ BuiltInId::rgb_2_yuv_Float3_YuvCscStandardEXT1,
+ BuiltInName::rgb_2_yuv,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p20B00H,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpRgb_2_yuv,
+ false);
+constexpr const TFunction yuv_2_rgb_20B00H(
+ BuiltInId::yuv_2_rgb_Float3_YuvCscStandardEXT1,
+ BuiltInName::yuv_2_rgb,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p20B00H,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpYuv_2_rgb,
+ false);
+constexpr const TFunction dFdxExt_00B(BuiltInId::dFdxExt_Float1,
+ BuiltInName::dFdxExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdxExt_10B(BuiltInId::dFdxExt_Float2,
+ BuiltInName::dFdxExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdxExt_20B(BuiltInId::dFdxExt_Float3,
+ BuiltInName::dFdxExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdxExt_30B(BuiltInId::dFdxExt_Float4,
+ BuiltInName::dFdxExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdyExt_00B(BuiltInId::dFdyExt_Float1,
+ BuiltInName::dFdyExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdyExt_10B(BuiltInId::dFdyExt_Float2,
+ BuiltInName::dFdyExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdyExt_20B(BuiltInId::dFdyExt_Float3,
+ BuiltInName::dFdyExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdyExt_30B(BuiltInId::dFdyExt_Float4,
+ BuiltInName::dFdyExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction fwidthExt_00B(BuiltInId::fwidthExt_Float1,
+ BuiltInName::fwidthExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidthExt_10B(BuiltInId::fwidthExt_Float2,
+ BuiltInName::fwidthExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidthExt_20B(BuiltInId::fwidthExt_Float3,
+ BuiltInName::fwidthExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidthExt_30B(BuiltInId::fwidthExt_Float4,
+ BuiltInName::fwidthExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction dFdx_00B(BuiltInId::dFdx_Float1,
+ BuiltInName::dFdx,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdx_10B(BuiltInId::dFdx_Float2,
+ BuiltInName::dFdx,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdx_20B(BuiltInId::dFdx_Float3,
+ BuiltInName::dFdx,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdx_30B(BuiltInId::dFdx_Float4,
+ BuiltInName::dFdx,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdy_00B(BuiltInId::dFdy_Float1,
+ BuiltInName::dFdy,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdy_10B(BuiltInId::dFdy_Float2,
+ BuiltInName::dFdy,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdy_20B(BuiltInId::dFdy_Float3,
+ BuiltInName::dFdy,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdy_30B(BuiltInId::dFdy_Float4,
+ BuiltInName::dFdy,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction fwidth_00B(BuiltInId::fwidth_Float1,
+ BuiltInName::fwidth,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidth_10B(BuiltInId::fwidth_Float2,
+ BuiltInName::fwidth,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidth_20B(BuiltInId::fwidth_Float3,
+ BuiltInName::fwidth,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidth_30B(BuiltInId::fwidth_Float4,
+ BuiltInName::fwidth,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction interpolateAtCentroid_00B(
+ BuiltInId::interpolateAtCentroid_Float1,
+ BuiltInName::interpolateAtCentroid,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroid_10B(
+ BuiltInId::interpolateAtCentroid_Float2,
+ BuiltInName::interpolateAtCentroid,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroid_20B(
+ BuiltInId::interpolateAtCentroid_Float3,
+ BuiltInName::interpolateAtCentroid,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroid_30B(
+ BuiltInId::interpolateAtCentroid_Float4,
+ BuiltInName::interpolateAtCentroid,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtSample_00B00D(
+ BuiltInId::interpolateAtSample_Float1_Int1,
+ BuiltInName::interpolateAtSample,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSample_10B00D(
+ BuiltInId::interpolateAtSample_Float2_Int1,
+ BuiltInName::interpolateAtSample,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSample_20B00D(
+ BuiltInId::interpolateAtSample_Float3_Int1,
+ BuiltInName::interpolateAtSample,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSample_30B00D(
+ BuiltInId::interpolateAtSample_Float4_Int1,
+ BuiltInName::interpolateAtSample,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtOffset_00B10B(
+ BuiltInId::interpolateAtOffset_Float1_Float2,
+ BuiltInName::interpolateAtOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffset_10B10B(
+ BuiltInId::interpolateAtOffset_Float2_Float2,
+ BuiltInName::interpolateAtOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffset_20B10B(
+ BuiltInId::interpolateAtOffset_Float3_Float2,
+ BuiltInName::interpolateAtOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffset_30B10B(
+ BuiltInId::interpolateAtOffset_Float4_Float2,
+ BuiltInName::interpolateAtOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtCentroidExt_00B(
+ BuiltInId::interpolateAtCentroidExt_Float1,
+ BuiltInName::interpolateAtCentroidExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroidExt_10B(
+ BuiltInId::interpolateAtCentroidExt_Float2,
+ BuiltInName::interpolateAtCentroidExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroidExt_20B(
+ BuiltInId::interpolateAtCentroidExt_Float3,
+ BuiltInName::interpolateAtCentroidExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroidExt_30B(
+ BuiltInId::interpolateAtCentroidExt_Float4,
+ BuiltInName::interpolateAtCentroidExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtSampleExt_00B00D(
+ BuiltInId::interpolateAtSampleExt_Float1_Int1,
+ BuiltInName::interpolateAtSampleExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p00B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSampleExt_10B00D(
+ BuiltInId::interpolateAtSampleExt_Float2_Int1,
+ BuiltInName::interpolateAtSampleExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p10B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSampleExt_20B00D(
+ BuiltInId::interpolateAtSampleExt_Float3_Int1,
+ BuiltInName::interpolateAtSampleExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p20B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSampleExt_30B00D(
+ BuiltInId::interpolateAtSampleExt_Float4_Int1,
+ BuiltInName::interpolateAtSampleExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p30B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtOffsetExt_00B10B(
+ BuiltInId::interpolateAtOffsetExt_Float1_Float2,
+ BuiltInName::interpolateAtOffsetExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p00B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffsetExt_10B10B(
+ BuiltInId::interpolateAtOffsetExt_Float2_Float2,
+ BuiltInName::interpolateAtOffsetExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffsetExt_20B10B(
+ BuiltInId::interpolateAtOffsetExt_Float3_Float2,
+ BuiltInName::interpolateAtOffsetExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p20B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffsetExt_30B10B(
+ BuiltInId::interpolateAtOffsetExt_Float4_Float2,
+ BuiltInName::interpolateAtOffsetExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p30B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction atomicCounter_00G(
+ BuiltInId::atomicCounter_AtomicCounter1,
+ BuiltInName::atomicCounter,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00G,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicCounter,
+ false);
+constexpr const TFunction atomicCounterIncrement_00G(
+ BuiltInId::atomicCounterIncrement_AtomicCounter1,
+ BuiltInName::atomicCounterIncrement,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00G,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicCounterIncrement,
+ false);
+constexpr const TFunction atomicCounterDecrement_00G(
+ BuiltInId::atomicCounterDecrement_AtomicCounter1,
+ BuiltInName::atomicCounterDecrement,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00G,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicCounterDecrement,
+ false);
+constexpr const TFunction atomicAdd_00E00E(
+ BuiltInId::atomicAdd_UInt1_UInt1,
+ BuiltInName::atomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicAdd,
+ false);
+constexpr const TFunction atomicAdd_00D00D(BuiltInId::atomicAdd_Int1_Int1,
+ BuiltInName::atomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicAdd,
+ false);
+constexpr const TFunction atomicMin_00E00E(
+ BuiltInId::atomicMin_UInt1_UInt1,
+ BuiltInName::atomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicMin,
+ false);
+constexpr const TFunction atomicMin_00D00D(BuiltInId::atomicMin_Int1_Int1,
+ BuiltInName::atomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicMin,
+ false);
+constexpr const TFunction atomicMax_00E00E(
+ BuiltInId::atomicMax_UInt1_UInt1,
+ BuiltInName::atomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicMax,
+ false);
+constexpr const TFunction atomicMax_00D00D(BuiltInId::atomicMax_Int1_Int1,
+ BuiltInName::atomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicMax,
+ false);
+constexpr const TFunction atomicAnd_00E00E(
+ BuiltInId::atomicAnd_UInt1_UInt1,
+ BuiltInName::atomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicAnd,
+ false);
+constexpr const TFunction atomicAnd_00D00D(BuiltInId::atomicAnd_Int1_Int1,
+ BuiltInName::atomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicAnd,
+ false);
+constexpr const TFunction atomicOr_00E00E(BuiltInId::atomicOr_UInt1_UInt1,
+ BuiltInName::atomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicOr,
+ false);
+constexpr const TFunction atomicOr_00D00D(BuiltInId::atomicOr_Int1_Int1,
+ BuiltInName::atomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicOr,
+ false);
+constexpr const TFunction atomicXor_00E00E(
+ BuiltInId::atomicXor_UInt1_UInt1,
+ BuiltInName::atomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicXor,
+ false);
+constexpr const TFunction atomicXor_00D00D(BuiltInId::atomicXor_Int1_Int1,
+ BuiltInName::atomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicXor,
+ false);
+constexpr const TFunction atomicExchange_00E00E(
+ BuiltInId::atomicExchange_UInt1_UInt1,
+ BuiltInName::atomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicExchange,
+ false);
+constexpr const TFunction atomicExchange_00D00D(
+ BuiltInId::atomicExchange_Int1_Int1,
+ BuiltInName::atomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicExchange,
+ false);
+constexpr const TFunction atomicCompSwap_00E00E00E(
+ BuiltInId::atomicCompSwap_UInt1_UInt1_UInt1,
+ BuiltInName::atomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicCompSwap,
+ false);
+constexpr const TFunction atomicCompSwap_00D00D00D(
+ BuiltInId::atomicCompSwap_Int1_Int1_Int1,
+ BuiltInName::atomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicCompSwap,
+ false);
+constexpr const TFunction imageSize_00z(BuiltInId::imageSize_Image2D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01K(BuiltInId::imageSize_IImage2D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01V(BuiltInId::imageSize_UImage2D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01A(BuiltInId::imageSize_Image3D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01L(BuiltInId::imageSize_IImage3D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01W(BuiltInId::imageSize_UImage3D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01B(BuiltInId::imageSize_Image2DArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01M(BuiltInId::imageSize_IImage2DArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01X(BuiltInId::imageSize_UImage2DArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01C(BuiltInId::imageSize_ImageCube1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01N(BuiltInId::imageSize_IImageCube1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01Y(BuiltInId::imageSize_UImageCube1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01H(BuiltInId::imageSize_ImageCubeArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01S(BuiltInId::imageSize_IImageCubeArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01d(BuiltInId::imageSize_UImageCubeArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01H(BuiltInId::imageSizeExt_ImageCubeArray1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01H20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01S(BuiltInId::imageSizeExt_IImageCubeArray1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01S20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01d(BuiltInId::imageSizeExt_UImageCubeArray1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01d20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01J(BuiltInId::imageSize_ImageBuffer1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01U(BuiltInId::imageSize_IImageBuffer1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01f(BuiltInId::imageSize_UImageBuffer1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01J(
+ BuiltInId::imageSizeExt_ImageBuffer1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01J00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01U(
+ BuiltInId::imageSizeExt_IImageBuffer1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01U00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01f(
+ BuiltInId::imageSizeExt_UImageBuffer1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01f00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageStore_00z10D30B(
+ BuiltInId::imageStore_Image2D1_Int2_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01K10D30D(
+ BuiltInId::imageStore_IImage2D1_Int2_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01V10D30E(
+ BuiltInId::imageStore_UImage2D1_Int2_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01A20D30B(
+ BuiltInId::imageStore_Image3D1_Int3_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01L20D30D(
+ BuiltInId::imageStore_IImage3D1_Int3_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01W20D30E(
+ BuiltInId::imageStore_UImage3D1_Int3_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01B20D30B(
+ BuiltInId::imageStore_Image2DArray1_Int3_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01M20D30D(
+ BuiltInId::imageStore_IImage2DArray1_Int3_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01X20D30E(
+ BuiltInId::imageStore_UImage2DArray1_Int3_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01C20D30B(
+ BuiltInId::imageStore_ImageCube1_Int3_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01N20D30D(
+ BuiltInId::imageStore_IImageCube1_Int3_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01Y20D30E(
+ BuiltInId::imageStore_UImageCube1_Int3_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01H20D30B(
+ BuiltInId::imageStore_ImageCubeArray1_Int3_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01S20D30D(
+ BuiltInId::imageStore_IImageCubeArray1_Int3_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01d20D30E(
+ BuiltInId::imageStore_UImageCubeArray1_Int3_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01H20D30B(
+ BuiltInId::imageStoreExt_ImageCubeArray1_Int3_Float4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01H20D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01S20D30D(
+ BuiltInId::imageStoreExt_IImageCubeArray1_Int3_Int4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01S20D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01d20D30E(
+ BuiltInId::imageStoreExt_UImageCubeArray1_Int3_UInt4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01d20D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01J00D30B(
+ BuiltInId::imageStore_ImageBuffer1_Int1_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01U00D30D(
+ BuiltInId::imageStore_IImageBuffer1_Int1_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01f00D30E(
+ BuiltInId::imageStore_UImageBuffer1_Int1_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01J00D30B(
+ BuiltInId::imageStoreExt_ImageBuffer1_Int1_Float4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01J00D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01U00D30D(
+ BuiltInId::imageStoreExt_IImageBuffer1_Int1_Int4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01U00D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01f00D30E(
+ BuiltInId::imageStoreExt_UImageBuffer1_Int1_UInt4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01f00D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageLoad_00z10D(
+ BuiltInId::imageLoad_Image2D1_Int2,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01K10D(BuiltInId::imageLoad_IImage2D1_Int2,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01V10D(
+ BuiltInId::imageLoad_UImage2D1_Int2,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01A20D(
+ BuiltInId::imageLoad_Image3D1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01L20D(BuiltInId::imageLoad_IImage3D1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01W20D(
+ BuiltInId::imageLoad_UImage3D1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01B20D(
+ BuiltInId::imageLoad_Image2DArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01M20D(BuiltInId::imageLoad_IImage2DArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01X20D(
+ BuiltInId::imageLoad_UImage2DArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01C20D(
+ BuiltInId::imageLoad_ImageCube1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01N20D(BuiltInId::imageLoad_IImageCube1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01Y20D(
+ BuiltInId::imageLoad_UImageCube1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01H20D(
+ BuiltInId::imageLoad_ImageCubeArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01S20D(BuiltInId::imageLoad_IImageCubeArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01d20D(
+ BuiltInId::imageLoad_UImageCubeArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01H20D(
+ BuiltInId::imageLoadExt_ImageCubeArray1_Int3,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01H20D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01S20D(
+ BuiltInId::imageLoadExt_IImageCubeArray1_Int3,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01S20D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01d20D(
+ BuiltInId::imageLoadExt_UImageCubeArray1_Int3,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01d20D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01J00D(
+ BuiltInId::imageLoad_ImageBuffer1_Int1,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01U00D(BuiltInId::imageLoad_IImageBuffer1_Int1,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01f00D(
+ BuiltInId::imageLoad_UImageBuffer1_Int1,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01J00D(
+ BuiltInId::imageLoadExt_ImageBuffer1_Int1,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01J00D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01U00D(
+ BuiltInId::imageLoadExt_IImageBuffer1_Int1,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01U00D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01f00D(
+ BuiltInId::imageLoadExt_UImageBuffer1_Int1,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01f00D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageAtomicAdd_00z10D00E(
+ BuiltInId::imageAtomicAdd_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01K10D00E(
+ BuiltInId::imageAtomicAdd_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01V10D00E(
+ BuiltInId::imageAtomicAdd_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01A20D00E(
+ BuiltInId::imageAtomicAdd_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01L20D00E(
+ BuiltInId::imageAtomicAdd_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01W20D00E(
+ BuiltInId::imageAtomicAdd_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01C20D00E(
+ BuiltInId::imageAtomicAdd_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01N20D00E(
+ BuiltInId::imageAtomicAdd_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Y20D00E(
+ BuiltInId::imageAtomicAdd_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01J00D00E(
+ BuiltInId::imageAtomicAdd_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01U00D00E(
+ BuiltInId::imageAtomicAdd_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01f00D00E(
+ BuiltInId::imageAtomicAdd_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01B20D00E(
+ BuiltInId::imageAtomicAdd_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01M20D00E(
+ BuiltInId::imageAtomicAdd_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01X20D00E(
+ BuiltInId::imageAtomicAdd_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01H20D00E(
+ BuiltInId::imageAtomicAdd_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01S20D00E(
+ BuiltInId::imageAtomicAdd_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01d20D00E(
+ BuiltInId::imageAtomicAdd_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01D00D00E(
+ BuiltInId::imageAtomicAdd_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01O00D00E(
+ BuiltInId::imageAtomicAdd_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Z00D00E(
+ BuiltInId::imageAtomicAdd_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01E10D00E(
+ BuiltInId::imageAtomicAdd_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01P10D00E(
+ BuiltInId::imageAtomicAdd_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01a10D00E(
+ BuiltInId::imageAtomicAdd_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01I10D00E(
+ BuiltInId::imageAtomicAdd_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01T10D00E(
+ BuiltInId::imageAtomicAdd_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01e10D00E(
+ BuiltInId::imageAtomicAdd_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01F10D00D00E(
+ BuiltInId::imageAtomicAdd_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Q10D00D00E(
+ BuiltInId::imageAtomicAdd_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01b10D00D00E(
+ BuiltInId::imageAtomicAdd_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01G20D00D00E(
+ BuiltInId::imageAtomicAdd_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01R20D00D00E(
+ BuiltInId::imageAtomicAdd_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01c20D00D00E(
+ BuiltInId::imageAtomicAdd_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_00z10D00D(
+ BuiltInId::imageAtomicAdd_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01K10D00D(
+ BuiltInId::imageAtomicAdd_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01V10D00D(
+ BuiltInId::imageAtomicAdd_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01A20D00D(
+ BuiltInId::imageAtomicAdd_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01L20D00D(
+ BuiltInId::imageAtomicAdd_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01W20D00D(
+ BuiltInId::imageAtomicAdd_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01C20D00D(
+ BuiltInId::imageAtomicAdd_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01N20D00D(
+ BuiltInId::imageAtomicAdd_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Y20D00D(
+ BuiltInId::imageAtomicAdd_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01J00D00D(
+ BuiltInId::imageAtomicAdd_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01U00D00D(
+ BuiltInId::imageAtomicAdd_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01f00D00D(
+ BuiltInId::imageAtomicAdd_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01B20D00D(
+ BuiltInId::imageAtomicAdd_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01M20D00D(
+ BuiltInId::imageAtomicAdd_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01X20D00D(
+ BuiltInId::imageAtomicAdd_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01H20D00D(
+ BuiltInId::imageAtomicAdd_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01S20D00D(
+ BuiltInId::imageAtomicAdd_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01d20D00D(
+ BuiltInId::imageAtomicAdd_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01D00D00D(
+ BuiltInId::imageAtomicAdd_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01O00D00D(
+ BuiltInId::imageAtomicAdd_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Z00D00D(
+ BuiltInId::imageAtomicAdd_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01E10D00D(
+ BuiltInId::imageAtomicAdd_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01P10D00D(
+ BuiltInId::imageAtomicAdd_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01a10D00D(
+ BuiltInId::imageAtomicAdd_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01I10D00D(
+ BuiltInId::imageAtomicAdd_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01T10D00D(
+ BuiltInId::imageAtomicAdd_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01e10D00D(
+ BuiltInId::imageAtomicAdd_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01F10D00D00D(
+ BuiltInId::imageAtomicAdd_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Q10D00D00D(
+ BuiltInId::imageAtomicAdd_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01b10D00D00D(
+ BuiltInId::imageAtomicAdd_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01G20D00D00D(
+ BuiltInId::imageAtomicAdd_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01R20D00D00D(
+ BuiltInId::imageAtomicAdd_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01c20D00D00D(
+ BuiltInId::imageAtomicAdd_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicMin_00z10D00E(
+ BuiltInId::imageAtomicMin_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01K10D00E(
+ BuiltInId::imageAtomicMin_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01V10D00E(
+ BuiltInId::imageAtomicMin_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01A20D00E(
+ BuiltInId::imageAtomicMin_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01L20D00E(
+ BuiltInId::imageAtomicMin_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01W20D00E(
+ BuiltInId::imageAtomicMin_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01C20D00E(
+ BuiltInId::imageAtomicMin_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01N20D00E(
+ BuiltInId::imageAtomicMin_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Y20D00E(
+ BuiltInId::imageAtomicMin_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01J00D00E(
+ BuiltInId::imageAtomicMin_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01U00D00E(
+ BuiltInId::imageAtomicMin_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01f00D00E(
+ BuiltInId::imageAtomicMin_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01B20D00E(
+ BuiltInId::imageAtomicMin_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01M20D00E(
+ BuiltInId::imageAtomicMin_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01X20D00E(
+ BuiltInId::imageAtomicMin_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01H20D00E(
+ BuiltInId::imageAtomicMin_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01S20D00E(
+ BuiltInId::imageAtomicMin_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01d20D00E(
+ BuiltInId::imageAtomicMin_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01D00D00E(
+ BuiltInId::imageAtomicMin_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01O00D00E(
+ BuiltInId::imageAtomicMin_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Z00D00E(
+ BuiltInId::imageAtomicMin_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01E10D00E(
+ BuiltInId::imageAtomicMin_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01P10D00E(
+ BuiltInId::imageAtomicMin_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01a10D00E(
+ BuiltInId::imageAtomicMin_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01I10D00E(
+ BuiltInId::imageAtomicMin_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01T10D00E(
+ BuiltInId::imageAtomicMin_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01e10D00E(
+ BuiltInId::imageAtomicMin_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01F10D00D00E(
+ BuiltInId::imageAtomicMin_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Q10D00D00E(
+ BuiltInId::imageAtomicMin_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01b10D00D00E(
+ BuiltInId::imageAtomicMin_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01G20D00D00E(
+ BuiltInId::imageAtomicMin_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01R20D00D00E(
+ BuiltInId::imageAtomicMin_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01c20D00D00E(
+ BuiltInId::imageAtomicMin_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_00z10D00D(
+ BuiltInId::imageAtomicMin_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01K10D00D(
+ BuiltInId::imageAtomicMin_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01V10D00D(
+ BuiltInId::imageAtomicMin_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01A20D00D(
+ BuiltInId::imageAtomicMin_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01L20D00D(
+ BuiltInId::imageAtomicMin_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01W20D00D(
+ BuiltInId::imageAtomicMin_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01C20D00D(
+ BuiltInId::imageAtomicMin_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01N20D00D(
+ BuiltInId::imageAtomicMin_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Y20D00D(
+ BuiltInId::imageAtomicMin_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01J00D00D(
+ BuiltInId::imageAtomicMin_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01U00D00D(
+ BuiltInId::imageAtomicMin_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01f00D00D(
+ BuiltInId::imageAtomicMin_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01B20D00D(
+ BuiltInId::imageAtomicMin_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01M20D00D(
+ BuiltInId::imageAtomicMin_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01X20D00D(
+ BuiltInId::imageAtomicMin_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01H20D00D(
+ BuiltInId::imageAtomicMin_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01S20D00D(
+ BuiltInId::imageAtomicMin_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01d20D00D(
+ BuiltInId::imageAtomicMin_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01D00D00D(
+ BuiltInId::imageAtomicMin_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01O00D00D(
+ BuiltInId::imageAtomicMin_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Z00D00D(
+ BuiltInId::imageAtomicMin_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01E10D00D(
+ BuiltInId::imageAtomicMin_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01P10D00D(
+ BuiltInId::imageAtomicMin_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01a10D00D(
+ BuiltInId::imageAtomicMin_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01I10D00D(
+ BuiltInId::imageAtomicMin_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01T10D00D(
+ BuiltInId::imageAtomicMin_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01e10D00D(
+ BuiltInId::imageAtomicMin_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01F10D00D00D(
+ BuiltInId::imageAtomicMin_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Q10D00D00D(
+ BuiltInId::imageAtomicMin_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01b10D00D00D(
+ BuiltInId::imageAtomicMin_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01G20D00D00D(
+ BuiltInId::imageAtomicMin_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01R20D00D00D(
+ BuiltInId::imageAtomicMin_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01c20D00D00D(
+ BuiltInId::imageAtomicMin_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMax_00z10D00E(
+ BuiltInId::imageAtomicMax_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01K10D00E(
+ BuiltInId::imageAtomicMax_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01V10D00E(
+ BuiltInId::imageAtomicMax_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01A20D00E(
+ BuiltInId::imageAtomicMax_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01L20D00E(
+ BuiltInId::imageAtomicMax_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01W20D00E(
+ BuiltInId::imageAtomicMax_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01C20D00E(
+ BuiltInId::imageAtomicMax_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01N20D00E(
+ BuiltInId::imageAtomicMax_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Y20D00E(
+ BuiltInId::imageAtomicMax_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01J00D00E(
+ BuiltInId::imageAtomicMax_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01U00D00E(
+ BuiltInId::imageAtomicMax_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01f00D00E(
+ BuiltInId::imageAtomicMax_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01B20D00E(
+ BuiltInId::imageAtomicMax_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01M20D00E(
+ BuiltInId::imageAtomicMax_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01X20D00E(
+ BuiltInId::imageAtomicMax_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01H20D00E(
+ BuiltInId::imageAtomicMax_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01S20D00E(
+ BuiltInId::imageAtomicMax_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01d20D00E(
+ BuiltInId::imageAtomicMax_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01D00D00E(
+ BuiltInId::imageAtomicMax_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01O00D00E(
+ BuiltInId::imageAtomicMax_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Z00D00E(
+ BuiltInId::imageAtomicMax_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01E10D00E(
+ BuiltInId::imageAtomicMax_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01P10D00E(
+ BuiltInId::imageAtomicMax_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01a10D00E(
+ BuiltInId::imageAtomicMax_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01I10D00E(
+ BuiltInId::imageAtomicMax_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01T10D00E(
+ BuiltInId::imageAtomicMax_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01e10D00E(
+ BuiltInId::imageAtomicMax_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01F10D00D00E(
+ BuiltInId::imageAtomicMax_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Q10D00D00E(
+ BuiltInId::imageAtomicMax_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01b10D00D00E(
+ BuiltInId::imageAtomicMax_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01G20D00D00E(
+ BuiltInId::imageAtomicMax_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01R20D00D00E(
+ BuiltInId::imageAtomicMax_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01c20D00D00E(
+ BuiltInId::imageAtomicMax_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_00z10D00D(
+ BuiltInId::imageAtomicMax_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01K10D00D(
+ BuiltInId::imageAtomicMax_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01V10D00D(
+ BuiltInId::imageAtomicMax_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01A20D00D(
+ BuiltInId::imageAtomicMax_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01L20D00D(
+ BuiltInId::imageAtomicMax_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01W20D00D(
+ BuiltInId::imageAtomicMax_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01C20D00D(
+ BuiltInId::imageAtomicMax_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01N20D00D(
+ BuiltInId::imageAtomicMax_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Y20D00D(
+ BuiltInId::imageAtomicMax_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01J00D00D(
+ BuiltInId::imageAtomicMax_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01U00D00D(
+ BuiltInId::imageAtomicMax_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01f00D00D(
+ BuiltInId::imageAtomicMax_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01B20D00D(
+ BuiltInId::imageAtomicMax_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01M20D00D(
+ BuiltInId::imageAtomicMax_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01X20D00D(
+ BuiltInId::imageAtomicMax_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01H20D00D(
+ BuiltInId::imageAtomicMax_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01S20D00D(
+ BuiltInId::imageAtomicMax_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01d20D00D(
+ BuiltInId::imageAtomicMax_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01D00D00D(
+ BuiltInId::imageAtomicMax_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01O00D00D(
+ BuiltInId::imageAtomicMax_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Z00D00D(
+ BuiltInId::imageAtomicMax_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01E10D00D(
+ BuiltInId::imageAtomicMax_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01P10D00D(
+ BuiltInId::imageAtomicMax_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01a10D00D(
+ BuiltInId::imageAtomicMax_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01I10D00D(
+ BuiltInId::imageAtomicMax_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01T10D00D(
+ BuiltInId::imageAtomicMax_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01e10D00D(
+ BuiltInId::imageAtomicMax_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01F10D00D00D(
+ BuiltInId::imageAtomicMax_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Q10D00D00D(
+ BuiltInId::imageAtomicMax_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01b10D00D00D(
+ BuiltInId::imageAtomicMax_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01G20D00D00D(
+ BuiltInId::imageAtomicMax_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01R20D00D00D(
+ BuiltInId::imageAtomicMax_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01c20D00D00D(
+ BuiltInId::imageAtomicMax_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicAnd_00z10D00E(
+ BuiltInId::imageAtomicAnd_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01K10D00E(
+ BuiltInId::imageAtomicAnd_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01V10D00E(
+ BuiltInId::imageAtomicAnd_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01A20D00E(
+ BuiltInId::imageAtomicAnd_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01L20D00E(
+ BuiltInId::imageAtomicAnd_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01W20D00E(
+ BuiltInId::imageAtomicAnd_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01C20D00E(
+ BuiltInId::imageAtomicAnd_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01N20D00E(
+ BuiltInId::imageAtomicAnd_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Y20D00E(
+ BuiltInId::imageAtomicAnd_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01J00D00E(
+ BuiltInId::imageAtomicAnd_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01U00D00E(
+ BuiltInId::imageAtomicAnd_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01f00D00E(
+ BuiltInId::imageAtomicAnd_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01B20D00E(
+ BuiltInId::imageAtomicAnd_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01M20D00E(
+ BuiltInId::imageAtomicAnd_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01X20D00E(
+ BuiltInId::imageAtomicAnd_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01H20D00E(
+ BuiltInId::imageAtomicAnd_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01S20D00E(
+ BuiltInId::imageAtomicAnd_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01d20D00E(
+ BuiltInId::imageAtomicAnd_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01D00D00E(
+ BuiltInId::imageAtomicAnd_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01O00D00E(
+ BuiltInId::imageAtomicAnd_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Z00D00E(
+ BuiltInId::imageAtomicAnd_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01E10D00E(
+ BuiltInId::imageAtomicAnd_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01P10D00E(
+ BuiltInId::imageAtomicAnd_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01a10D00E(
+ BuiltInId::imageAtomicAnd_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01I10D00E(
+ BuiltInId::imageAtomicAnd_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01T10D00E(
+ BuiltInId::imageAtomicAnd_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01e10D00E(
+ BuiltInId::imageAtomicAnd_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01F10D00D00E(
+ BuiltInId::imageAtomicAnd_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Q10D00D00E(
+ BuiltInId::imageAtomicAnd_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01b10D00D00E(
+ BuiltInId::imageAtomicAnd_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01G20D00D00E(
+ BuiltInId::imageAtomicAnd_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01R20D00D00E(
+ BuiltInId::imageAtomicAnd_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01c20D00D00E(
+ BuiltInId::imageAtomicAnd_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_00z10D00D(
+ BuiltInId::imageAtomicAnd_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01K10D00D(
+ BuiltInId::imageAtomicAnd_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01V10D00D(
+ BuiltInId::imageAtomicAnd_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01A20D00D(
+ BuiltInId::imageAtomicAnd_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01L20D00D(
+ BuiltInId::imageAtomicAnd_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01W20D00D(
+ BuiltInId::imageAtomicAnd_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01C20D00D(
+ BuiltInId::imageAtomicAnd_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01N20D00D(
+ BuiltInId::imageAtomicAnd_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Y20D00D(
+ BuiltInId::imageAtomicAnd_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01J00D00D(
+ BuiltInId::imageAtomicAnd_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01U00D00D(
+ BuiltInId::imageAtomicAnd_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01f00D00D(
+ BuiltInId::imageAtomicAnd_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01B20D00D(
+ BuiltInId::imageAtomicAnd_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01M20D00D(
+ BuiltInId::imageAtomicAnd_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01X20D00D(
+ BuiltInId::imageAtomicAnd_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01H20D00D(
+ BuiltInId::imageAtomicAnd_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01S20D00D(
+ BuiltInId::imageAtomicAnd_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01d20D00D(
+ BuiltInId::imageAtomicAnd_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01D00D00D(
+ BuiltInId::imageAtomicAnd_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01O00D00D(
+ BuiltInId::imageAtomicAnd_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Z00D00D(
+ BuiltInId::imageAtomicAnd_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01E10D00D(
+ BuiltInId::imageAtomicAnd_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01P10D00D(
+ BuiltInId::imageAtomicAnd_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01a10D00D(
+ BuiltInId::imageAtomicAnd_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01I10D00D(
+ BuiltInId::imageAtomicAnd_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01T10D00D(
+ BuiltInId::imageAtomicAnd_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01e10D00D(
+ BuiltInId::imageAtomicAnd_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01F10D00D00D(
+ BuiltInId::imageAtomicAnd_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Q10D00D00D(
+ BuiltInId::imageAtomicAnd_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01b10D00D00D(
+ BuiltInId::imageAtomicAnd_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01G20D00D00D(
+ BuiltInId::imageAtomicAnd_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01R20D00D00D(
+ BuiltInId::imageAtomicAnd_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01c20D00D00D(
+ BuiltInId::imageAtomicAnd_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicOr_00z10D00E(
+ BuiltInId::imageAtomicOr_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01K10D00E(
+ BuiltInId::imageAtomicOr_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01V10D00E(
+ BuiltInId::imageAtomicOr_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01A20D00E(
+ BuiltInId::imageAtomicOr_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01L20D00E(
+ BuiltInId::imageAtomicOr_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01W20D00E(
+ BuiltInId::imageAtomicOr_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01C20D00E(
+ BuiltInId::imageAtomicOr_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01N20D00E(
+ BuiltInId::imageAtomicOr_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Y20D00E(
+ BuiltInId::imageAtomicOr_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01J00D00E(
+ BuiltInId::imageAtomicOr_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01U00D00E(
+ BuiltInId::imageAtomicOr_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01f00D00E(
+ BuiltInId::imageAtomicOr_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01B20D00E(
+ BuiltInId::imageAtomicOr_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01M20D00E(
+ BuiltInId::imageAtomicOr_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01X20D00E(
+ BuiltInId::imageAtomicOr_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01H20D00E(
+ BuiltInId::imageAtomicOr_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01S20D00E(
+ BuiltInId::imageAtomicOr_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01d20D00E(
+ BuiltInId::imageAtomicOr_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01D00D00E(
+ BuiltInId::imageAtomicOr_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01O00D00E(
+ BuiltInId::imageAtomicOr_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Z00D00E(
+ BuiltInId::imageAtomicOr_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01E10D00E(
+ BuiltInId::imageAtomicOr_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01P10D00E(
+ BuiltInId::imageAtomicOr_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01a10D00E(
+ BuiltInId::imageAtomicOr_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01I10D00E(
+ BuiltInId::imageAtomicOr_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01T10D00E(
+ BuiltInId::imageAtomicOr_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01e10D00E(
+ BuiltInId::imageAtomicOr_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01F10D00D00E(
+ BuiltInId::imageAtomicOr_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Q10D00D00E(
+ BuiltInId::imageAtomicOr_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01b10D00D00E(
+ BuiltInId::imageAtomicOr_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01G20D00D00E(
+ BuiltInId::imageAtomicOr_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01R20D00D00E(
+ BuiltInId::imageAtomicOr_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01c20D00D00E(
+ BuiltInId::imageAtomicOr_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_00z10D00D(
+ BuiltInId::imageAtomicOr_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01K10D00D(
+ BuiltInId::imageAtomicOr_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01V10D00D(
+ BuiltInId::imageAtomicOr_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01A20D00D(
+ BuiltInId::imageAtomicOr_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01L20D00D(
+ BuiltInId::imageAtomicOr_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01W20D00D(
+ BuiltInId::imageAtomicOr_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01C20D00D(
+ BuiltInId::imageAtomicOr_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01N20D00D(
+ BuiltInId::imageAtomicOr_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Y20D00D(
+ BuiltInId::imageAtomicOr_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01J00D00D(
+ BuiltInId::imageAtomicOr_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01U00D00D(
+ BuiltInId::imageAtomicOr_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01f00D00D(
+ BuiltInId::imageAtomicOr_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01B20D00D(
+ BuiltInId::imageAtomicOr_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01M20D00D(
+ BuiltInId::imageAtomicOr_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01X20D00D(
+ BuiltInId::imageAtomicOr_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01H20D00D(
+ BuiltInId::imageAtomicOr_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01S20D00D(
+ BuiltInId::imageAtomicOr_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01d20D00D(
+ BuiltInId::imageAtomicOr_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01D00D00D(
+ BuiltInId::imageAtomicOr_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01O00D00D(
+ BuiltInId::imageAtomicOr_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Z00D00D(
+ BuiltInId::imageAtomicOr_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01E10D00D(
+ BuiltInId::imageAtomicOr_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01P10D00D(
+ BuiltInId::imageAtomicOr_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01a10D00D(
+ BuiltInId::imageAtomicOr_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01I10D00D(
+ BuiltInId::imageAtomicOr_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01T10D00D(
+ BuiltInId::imageAtomicOr_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01e10D00D(
+ BuiltInId::imageAtomicOr_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01F10D00D00D(
+ BuiltInId::imageAtomicOr_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Q10D00D00D(
+ BuiltInId::imageAtomicOr_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01b10D00D00D(
+ BuiltInId::imageAtomicOr_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01G20D00D00D(
+ BuiltInId::imageAtomicOr_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01R20D00D00D(
+ BuiltInId::imageAtomicOr_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01c20D00D00D(
+ BuiltInId::imageAtomicOr_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicXor_00z10D00E(
+ BuiltInId::imageAtomicXor_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01K10D00E(
+ BuiltInId::imageAtomicXor_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01V10D00E(
+ BuiltInId::imageAtomicXor_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01A20D00E(
+ BuiltInId::imageAtomicXor_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01L20D00E(
+ BuiltInId::imageAtomicXor_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01W20D00E(
+ BuiltInId::imageAtomicXor_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01C20D00E(
+ BuiltInId::imageAtomicXor_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01N20D00E(
+ BuiltInId::imageAtomicXor_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Y20D00E(
+ BuiltInId::imageAtomicXor_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01J00D00E(
+ BuiltInId::imageAtomicXor_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01U00D00E(
+ BuiltInId::imageAtomicXor_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01f00D00E(
+ BuiltInId::imageAtomicXor_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01B20D00E(
+ BuiltInId::imageAtomicXor_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01M20D00E(
+ BuiltInId::imageAtomicXor_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01X20D00E(
+ BuiltInId::imageAtomicXor_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01H20D00E(
+ BuiltInId::imageAtomicXor_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01S20D00E(
+ BuiltInId::imageAtomicXor_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01d20D00E(
+ BuiltInId::imageAtomicXor_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01D00D00E(
+ BuiltInId::imageAtomicXor_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01O00D00E(
+ BuiltInId::imageAtomicXor_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Z00D00E(
+ BuiltInId::imageAtomicXor_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01E10D00E(
+ BuiltInId::imageAtomicXor_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01P10D00E(
+ BuiltInId::imageAtomicXor_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01a10D00E(
+ BuiltInId::imageAtomicXor_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01I10D00E(
+ BuiltInId::imageAtomicXor_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01T10D00E(
+ BuiltInId::imageAtomicXor_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01e10D00E(
+ BuiltInId::imageAtomicXor_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01F10D00D00E(
+ BuiltInId::imageAtomicXor_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Q10D00D00E(
+ BuiltInId::imageAtomicXor_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01b10D00D00E(
+ BuiltInId::imageAtomicXor_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01G20D00D00E(
+ BuiltInId::imageAtomicXor_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01R20D00D00E(
+ BuiltInId::imageAtomicXor_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01c20D00D00E(
+ BuiltInId::imageAtomicXor_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_00z10D00D(
+ BuiltInId::imageAtomicXor_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01K10D00D(
+ BuiltInId::imageAtomicXor_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01V10D00D(
+ BuiltInId::imageAtomicXor_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01A20D00D(
+ BuiltInId::imageAtomicXor_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01L20D00D(
+ BuiltInId::imageAtomicXor_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01W20D00D(
+ BuiltInId::imageAtomicXor_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01C20D00D(
+ BuiltInId::imageAtomicXor_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01N20D00D(
+ BuiltInId::imageAtomicXor_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Y20D00D(
+ BuiltInId::imageAtomicXor_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01J00D00D(
+ BuiltInId::imageAtomicXor_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01U00D00D(
+ BuiltInId::imageAtomicXor_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01f00D00D(
+ BuiltInId::imageAtomicXor_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01B20D00D(
+ BuiltInId::imageAtomicXor_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01M20D00D(
+ BuiltInId::imageAtomicXor_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01X20D00D(
+ BuiltInId::imageAtomicXor_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01H20D00D(
+ BuiltInId::imageAtomicXor_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01S20D00D(
+ BuiltInId::imageAtomicXor_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01d20D00D(
+ BuiltInId::imageAtomicXor_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01D00D00D(
+ BuiltInId::imageAtomicXor_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01O00D00D(
+ BuiltInId::imageAtomicXor_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Z00D00D(
+ BuiltInId::imageAtomicXor_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01E10D00D(
+ BuiltInId::imageAtomicXor_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01P10D00D(
+ BuiltInId::imageAtomicXor_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01a10D00D(
+ BuiltInId::imageAtomicXor_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01I10D00D(
+ BuiltInId::imageAtomicXor_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01T10D00D(
+ BuiltInId::imageAtomicXor_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01e10D00D(
+ BuiltInId::imageAtomicXor_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01F10D00D00D(
+ BuiltInId::imageAtomicXor_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Q10D00D00D(
+ BuiltInId::imageAtomicXor_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01b10D00D00D(
+ BuiltInId::imageAtomicXor_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01G20D00D00D(
+ BuiltInId::imageAtomicXor_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01R20D00D00D(
+ BuiltInId::imageAtomicXor_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01c20D00D00D(
+ BuiltInId::imageAtomicXor_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicExchange_00z10D00E(
+ BuiltInId::imageAtomicExchange_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01K10D00E(
+ BuiltInId::imageAtomicExchange_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01V10D00E(
+ BuiltInId::imageAtomicExchange_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01A20D00E(
+ BuiltInId::imageAtomicExchange_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01L20D00E(
+ BuiltInId::imageAtomicExchange_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01W20D00E(
+ BuiltInId::imageAtomicExchange_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01C20D00E(
+ BuiltInId::imageAtomicExchange_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01N20D00E(
+ BuiltInId::imageAtomicExchange_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Y20D00E(
+ BuiltInId::imageAtomicExchange_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01J00D00E(
+ BuiltInId::imageAtomicExchange_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01U00D00E(
+ BuiltInId::imageAtomicExchange_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01f00D00E(
+ BuiltInId::imageAtomicExchange_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01B20D00E(
+ BuiltInId::imageAtomicExchange_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01M20D00E(
+ BuiltInId::imageAtomicExchange_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01X20D00E(
+ BuiltInId::imageAtomicExchange_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01H20D00E(
+ BuiltInId::imageAtomicExchange_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01S20D00E(
+ BuiltInId::imageAtomicExchange_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01d20D00E(
+ BuiltInId::imageAtomicExchange_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01D00D00E(
+ BuiltInId::imageAtomicExchange_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01O00D00E(
+ BuiltInId::imageAtomicExchange_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Z00D00E(
+ BuiltInId::imageAtomicExchange_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01E10D00E(
+ BuiltInId::imageAtomicExchange_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01P10D00E(
+ BuiltInId::imageAtomicExchange_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01a10D00E(
+ BuiltInId::imageAtomicExchange_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01I10D00E(
+ BuiltInId::imageAtomicExchange_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01T10D00E(
+ BuiltInId::imageAtomicExchange_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01e10D00E(
+ BuiltInId::imageAtomicExchange_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01F10D00D00E(
+ BuiltInId::imageAtomicExchange_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Q10D00D00E(
+ BuiltInId::imageAtomicExchange_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01b10D00D00E(
+ BuiltInId::imageAtomicExchange_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01G20D00D00E(
+ BuiltInId::imageAtomicExchange_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01R20D00D00E(
+ BuiltInId::imageAtomicExchange_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01c20D00D00E(
+ BuiltInId::imageAtomicExchange_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_00z10D00D(
+ BuiltInId::imageAtomicExchange_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01K10D00D(
+ BuiltInId::imageAtomicExchange_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01V10D00D(
+ BuiltInId::imageAtomicExchange_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01A20D00D(
+ BuiltInId::imageAtomicExchange_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01L20D00D(
+ BuiltInId::imageAtomicExchange_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01W20D00D(
+ BuiltInId::imageAtomicExchange_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01C20D00D(
+ BuiltInId::imageAtomicExchange_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01N20D00D(
+ BuiltInId::imageAtomicExchange_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Y20D00D(
+ BuiltInId::imageAtomicExchange_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01J00D00D(
+ BuiltInId::imageAtomicExchange_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01U00D00D(
+ BuiltInId::imageAtomicExchange_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01f00D00D(
+ BuiltInId::imageAtomicExchange_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01B20D00D(
+ BuiltInId::imageAtomicExchange_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01M20D00D(
+ BuiltInId::imageAtomicExchange_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01X20D00D(
+ BuiltInId::imageAtomicExchange_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01H20D00D(
+ BuiltInId::imageAtomicExchange_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01S20D00D(
+ BuiltInId::imageAtomicExchange_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01d20D00D(
+ BuiltInId::imageAtomicExchange_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01D00D00D(
+ BuiltInId::imageAtomicExchange_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01O00D00D(
+ BuiltInId::imageAtomicExchange_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Z00D00D(
+ BuiltInId::imageAtomicExchange_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01E10D00D(
+ BuiltInId::imageAtomicExchange_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01P10D00D(
+ BuiltInId::imageAtomicExchange_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01a10D00D(
+ BuiltInId::imageAtomicExchange_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01I10D00D(
+ BuiltInId::imageAtomicExchange_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01T10D00D(
+ BuiltInId::imageAtomicExchange_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01e10D00D(
+ BuiltInId::imageAtomicExchange_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01F10D00D00D(
+ BuiltInId::imageAtomicExchange_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Q10D00D00D(
+ BuiltInId::imageAtomicExchange_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01b10D00D00D(
+ BuiltInId::imageAtomicExchange_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01G20D00D00D(
+ BuiltInId::imageAtomicExchange_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01R20D00D00D(
+ BuiltInId::imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01c20D00D00D(
+ BuiltInId::imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_00z10D00B(
+ BuiltInId::imageAtomicExchange_Image2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01K10D00B(
+ BuiltInId::imageAtomicExchange_IImage2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01V10D00B(
+ BuiltInId::imageAtomicExchange_UImage2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01A20D00B(
+ BuiltInId::imageAtomicExchange_Image3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01L20D00B(
+ BuiltInId::imageAtomicExchange_IImage3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01W20D00B(
+ BuiltInId::imageAtomicExchange_UImage3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01C20D00B(
+ BuiltInId::imageAtomicExchange_ImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01N20D00B(
+ BuiltInId::imageAtomicExchange_IImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Y20D00B(
+ BuiltInId::imageAtomicExchange_UImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01J00D00B(
+ BuiltInId::imageAtomicExchange_ImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01U00D00B(
+ BuiltInId::imageAtomicExchange_IImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01f00D00B(
+ BuiltInId::imageAtomicExchange_UImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01B20D00B(
+ BuiltInId::imageAtomicExchange_Image2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01M20D00B(
+ BuiltInId::imageAtomicExchange_IImage2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01X20D00B(
+ BuiltInId::imageAtomicExchange_UImage2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01H20D00B(
+ BuiltInId::imageAtomicExchange_ImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01S20D00B(
+ BuiltInId::imageAtomicExchange_IImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01d20D00B(
+ BuiltInId::imageAtomicExchange_UImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01D00D00B(
+ BuiltInId::imageAtomicExchange_Image1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01O00D00B(
+ BuiltInId::imageAtomicExchange_IImage1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Z00D00B(
+ BuiltInId::imageAtomicExchange_UImage1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01E10D00B(
+ BuiltInId::imageAtomicExchange_Image1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01P10D00B(
+ BuiltInId::imageAtomicExchange_IImage1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01a10D00B(
+ BuiltInId::imageAtomicExchange_UImage1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01I10D00B(
+ BuiltInId::imageAtomicExchange_ImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01T10D00B(
+ BuiltInId::imageAtomicExchange_IImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01e10D00B(
+ BuiltInId::imageAtomicExchange_UImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01F10D00D00B(
+ BuiltInId::imageAtomicExchange_Image2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Q10D00D00B(
+ BuiltInId::imageAtomicExchange_IImage2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01b10D00D00B(
+ BuiltInId::imageAtomicExchange_UImage2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01G20D00D00B(
+ BuiltInId::imageAtomicExchange_Image2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01R20D00D00B(
+ BuiltInId::imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01c20D00D00B(
+ BuiltInId::imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicCompSwap_00z10D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01K10D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01V10D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01A20D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01L20D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01W20D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01C20D00E00E(
+ BuiltInId::imageAtomicCompSwap_ImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01N20D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Y20D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01J00D00E00E(
+ BuiltInId::imageAtomicCompSwap_ImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01U00D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01f00D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01B20D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01M20D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01X20D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01H20D00E00E(
+ BuiltInId::imageAtomicCompSwap_ImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01S20D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01d20D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01O00D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Z00D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01E10D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01P10D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01a10D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01I10D00E00E(
+ BuiltInId::imageAtomicCompSwap_ImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01T10D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01e10D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01F10D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Q10D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01b10D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01G20D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01R20D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01c20D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_00z10D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01K10D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01V10D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01A20D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01L20D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01W20D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01C20D00D00D(
+ BuiltInId::imageAtomicCompSwap_ImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01N20D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Y20D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01J00D00D00D(
+ BuiltInId::imageAtomicCompSwap_ImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01U00D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01f00D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01B20D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01M20D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01X20D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01H20D00D00D(
+ BuiltInId::imageAtomicCompSwap_ImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01S20D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01d20D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01O00D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Z00D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01E10D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01P10D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01a10D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01I10D00D00D(
+ BuiltInId::imageAtomicCompSwap_ImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01T10D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01e10D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01F10D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Q10D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01b10D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01G20D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01R20D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01c20D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicAddExt_00z10D00E(
+ BuiltInId::imageAtomicAddExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01K10D00E(
+ BuiltInId::imageAtomicAddExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01V10D00E(
+ BuiltInId::imageAtomicAddExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01A20D00E(
+ BuiltInId::imageAtomicAddExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01L20D00E(
+ BuiltInId::imageAtomicAddExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01W20D00E(
+ BuiltInId::imageAtomicAddExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01C20D00E(
+ BuiltInId::imageAtomicAddExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01N20D00E(
+ BuiltInId::imageAtomicAddExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Y20D00E(
+ BuiltInId::imageAtomicAddExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01J00D00E(
+ BuiltInId::imageAtomicAddExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01U00D00E(
+ BuiltInId::imageAtomicAddExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01f00D00E(
+ BuiltInId::imageAtomicAddExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01B20D00E(
+ BuiltInId::imageAtomicAddExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01M20D00E(
+ BuiltInId::imageAtomicAddExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01X20D00E(
+ BuiltInId::imageAtomicAddExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01H20D00E(
+ BuiltInId::imageAtomicAddExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01S20D00E(
+ BuiltInId::imageAtomicAddExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01d20D00E(
+ BuiltInId::imageAtomicAddExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01D00D00E(
+ BuiltInId::imageAtomicAddExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01O00D00E(
+ BuiltInId::imageAtomicAddExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Z00D00E(
+ BuiltInId::imageAtomicAddExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01E10D00E(
+ BuiltInId::imageAtomicAddExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01P10D00E(
+ BuiltInId::imageAtomicAddExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01a10D00E(
+ BuiltInId::imageAtomicAddExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01I10D00E(
+ BuiltInId::imageAtomicAddExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01T10D00E(
+ BuiltInId::imageAtomicAddExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01e10D00E(
+ BuiltInId::imageAtomicAddExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01F10D00D00E(
+ BuiltInId::imageAtomicAddExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Q10D00D00E(
+ BuiltInId::imageAtomicAddExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01b10D00D00E(
+ BuiltInId::imageAtomicAddExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01G20D00D00E(
+ BuiltInId::imageAtomicAddExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01R20D00D00E(
+ BuiltInId::imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01c20D00D00E(
+ BuiltInId::imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_00z10D00D(
+ BuiltInId::imageAtomicAddExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01K10D00D(
+ BuiltInId::imageAtomicAddExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01V10D00D(
+ BuiltInId::imageAtomicAddExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01A20D00D(
+ BuiltInId::imageAtomicAddExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01L20D00D(
+ BuiltInId::imageAtomicAddExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01W20D00D(
+ BuiltInId::imageAtomicAddExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01C20D00D(
+ BuiltInId::imageAtomicAddExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01N20D00D(
+ BuiltInId::imageAtomicAddExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Y20D00D(
+ BuiltInId::imageAtomicAddExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01J00D00D(
+ BuiltInId::imageAtomicAddExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01U00D00D(
+ BuiltInId::imageAtomicAddExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01f00D00D(
+ BuiltInId::imageAtomicAddExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01B20D00D(
+ BuiltInId::imageAtomicAddExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01M20D00D(
+ BuiltInId::imageAtomicAddExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01X20D00D(
+ BuiltInId::imageAtomicAddExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01H20D00D(
+ BuiltInId::imageAtomicAddExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01S20D00D(
+ BuiltInId::imageAtomicAddExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01d20D00D(
+ BuiltInId::imageAtomicAddExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01D00D00D(
+ BuiltInId::imageAtomicAddExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01O00D00D(
+ BuiltInId::imageAtomicAddExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Z00D00D(
+ BuiltInId::imageAtomicAddExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01E10D00D(
+ BuiltInId::imageAtomicAddExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01P10D00D(
+ BuiltInId::imageAtomicAddExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01a10D00D(
+ BuiltInId::imageAtomicAddExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01I10D00D(
+ BuiltInId::imageAtomicAddExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01T10D00D(
+ BuiltInId::imageAtomicAddExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01e10D00D(
+ BuiltInId::imageAtomicAddExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01F10D00D00D(
+ BuiltInId::imageAtomicAddExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Q10D00D00D(
+ BuiltInId::imageAtomicAddExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01b10D00D00D(
+ BuiltInId::imageAtomicAddExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01G20D00D00D(
+ BuiltInId::imageAtomicAddExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01R20D00D00D(
+ BuiltInId::imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01c20D00D00D(
+ BuiltInId::imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicMinExt_00z10D00E(
+ BuiltInId::imageAtomicMinExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01K10D00E(
+ BuiltInId::imageAtomicMinExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01V10D00E(
+ BuiltInId::imageAtomicMinExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01A20D00E(
+ BuiltInId::imageAtomicMinExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01L20D00E(
+ BuiltInId::imageAtomicMinExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01W20D00E(
+ BuiltInId::imageAtomicMinExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01C20D00E(
+ BuiltInId::imageAtomicMinExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01N20D00E(
+ BuiltInId::imageAtomicMinExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Y20D00E(
+ BuiltInId::imageAtomicMinExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01J00D00E(
+ BuiltInId::imageAtomicMinExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01U00D00E(
+ BuiltInId::imageAtomicMinExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01f00D00E(
+ BuiltInId::imageAtomicMinExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01B20D00E(
+ BuiltInId::imageAtomicMinExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01M20D00E(
+ BuiltInId::imageAtomicMinExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01X20D00E(
+ BuiltInId::imageAtomicMinExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01H20D00E(
+ BuiltInId::imageAtomicMinExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01S20D00E(
+ BuiltInId::imageAtomicMinExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01d20D00E(
+ BuiltInId::imageAtomicMinExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01D00D00E(
+ BuiltInId::imageAtomicMinExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01O00D00E(
+ BuiltInId::imageAtomicMinExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Z00D00E(
+ BuiltInId::imageAtomicMinExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01E10D00E(
+ BuiltInId::imageAtomicMinExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01P10D00E(
+ BuiltInId::imageAtomicMinExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01a10D00E(
+ BuiltInId::imageAtomicMinExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01I10D00E(
+ BuiltInId::imageAtomicMinExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01T10D00E(
+ BuiltInId::imageAtomicMinExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01e10D00E(
+ BuiltInId::imageAtomicMinExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01F10D00D00E(
+ BuiltInId::imageAtomicMinExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Q10D00D00E(
+ BuiltInId::imageAtomicMinExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01b10D00D00E(
+ BuiltInId::imageAtomicMinExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01G20D00D00E(
+ BuiltInId::imageAtomicMinExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01R20D00D00E(
+ BuiltInId::imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01c20D00D00E(
+ BuiltInId::imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_00z10D00D(
+ BuiltInId::imageAtomicMinExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01K10D00D(
+ BuiltInId::imageAtomicMinExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01V10D00D(
+ BuiltInId::imageAtomicMinExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01A20D00D(
+ BuiltInId::imageAtomicMinExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01L20D00D(
+ BuiltInId::imageAtomicMinExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01W20D00D(
+ BuiltInId::imageAtomicMinExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01C20D00D(
+ BuiltInId::imageAtomicMinExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01N20D00D(
+ BuiltInId::imageAtomicMinExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Y20D00D(
+ BuiltInId::imageAtomicMinExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01J00D00D(
+ BuiltInId::imageAtomicMinExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01U00D00D(
+ BuiltInId::imageAtomicMinExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01f00D00D(
+ BuiltInId::imageAtomicMinExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01B20D00D(
+ BuiltInId::imageAtomicMinExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01M20D00D(
+ BuiltInId::imageAtomicMinExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01X20D00D(
+ BuiltInId::imageAtomicMinExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01H20D00D(
+ BuiltInId::imageAtomicMinExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01S20D00D(
+ BuiltInId::imageAtomicMinExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01d20D00D(
+ BuiltInId::imageAtomicMinExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01D00D00D(
+ BuiltInId::imageAtomicMinExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01O00D00D(
+ BuiltInId::imageAtomicMinExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Z00D00D(
+ BuiltInId::imageAtomicMinExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01E10D00D(
+ BuiltInId::imageAtomicMinExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01P10D00D(
+ BuiltInId::imageAtomicMinExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01a10D00D(
+ BuiltInId::imageAtomicMinExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01I10D00D(
+ BuiltInId::imageAtomicMinExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01T10D00D(
+ BuiltInId::imageAtomicMinExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01e10D00D(
+ BuiltInId::imageAtomicMinExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01F10D00D00D(
+ BuiltInId::imageAtomicMinExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Q10D00D00D(
+ BuiltInId::imageAtomicMinExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01b10D00D00D(
+ BuiltInId::imageAtomicMinExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01G20D00D00D(
+ BuiltInId::imageAtomicMinExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01R20D00D00D(
+ BuiltInId::imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01c20D00D00D(
+ BuiltInId::imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMaxExt_00z10D00E(
+ BuiltInId::imageAtomicMaxExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01K10D00E(
+ BuiltInId::imageAtomicMaxExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01V10D00E(
+ BuiltInId::imageAtomicMaxExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01A20D00E(
+ BuiltInId::imageAtomicMaxExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01L20D00E(
+ BuiltInId::imageAtomicMaxExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01W20D00E(
+ BuiltInId::imageAtomicMaxExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01C20D00E(
+ BuiltInId::imageAtomicMaxExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01N20D00E(
+ BuiltInId::imageAtomicMaxExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Y20D00E(
+ BuiltInId::imageAtomicMaxExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01J00D00E(
+ BuiltInId::imageAtomicMaxExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01U00D00E(
+ BuiltInId::imageAtomicMaxExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01f00D00E(
+ BuiltInId::imageAtomicMaxExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01B20D00E(
+ BuiltInId::imageAtomicMaxExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01M20D00E(
+ BuiltInId::imageAtomicMaxExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01X20D00E(
+ BuiltInId::imageAtomicMaxExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01H20D00E(
+ BuiltInId::imageAtomicMaxExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01S20D00E(
+ BuiltInId::imageAtomicMaxExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01d20D00E(
+ BuiltInId::imageAtomicMaxExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01D00D00E(
+ BuiltInId::imageAtomicMaxExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01O00D00E(
+ BuiltInId::imageAtomicMaxExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Z00D00E(
+ BuiltInId::imageAtomicMaxExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01E10D00E(
+ BuiltInId::imageAtomicMaxExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01P10D00E(
+ BuiltInId::imageAtomicMaxExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01a10D00E(
+ BuiltInId::imageAtomicMaxExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01I10D00E(
+ BuiltInId::imageAtomicMaxExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01T10D00E(
+ BuiltInId::imageAtomicMaxExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01e10D00E(
+ BuiltInId::imageAtomicMaxExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01F10D00D00E(
+ BuiltInId::imageAtomicMaxExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Q10D00D00E(
+ BuiltInId::imageAtomicMaxExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01b10D00D00E(
+ BuiltInId::imageAtomicMaxExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01G20D00D00E(
+ BuiltInId::imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01R20D00D00E(
+ BuiltInId::imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01c20D00D00E(
+ BuiltInId::imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_00z10D00D(
+ BuiltInId::imageAtomicMaxExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01K10D00D(
+ BuiltInId::imageAtomicMaxExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01V10D00D(
+ BuiltInId::imageAtomicMaxExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01A20D00D(
+ BuiltInId::imageAtomicMaxExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01L20D00D(
+ BuiltInId::imageAtomicMaxExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01W20D00D(
+ BuiltInId::imageAtomicMaxExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01C20D00D(
+ BuiltInId::imageAtomicMaxExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01N20D00D(
+ BuiltInId::imageAtomicMaxExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Y20D00D(
+ BuiltInId::imageAtomicMaxExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01J00D00D(
+ BuiltInId::imageAtomicMaxExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01U00D00D(
+ BuiltInId::imageAtomicMaxExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01f00D00D(
+ BuiltInId::imageAtomicMaxExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01B20D00D(
+ BuiltInId::imageAtomicMaxExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01M20D00D(
+ BuiltInId::imageAtomicMaxExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01X20D00D(
+ BuiltInId::imageAtomicMaxExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01H20D00D(
+ BuiltInId::imageAtomicMaxExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01S20D00D(
+ BuiltInId::imageAtomicMaxExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01d20D00D(
+ BuiltInId::imageAtomicMaxExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01D00D00D(
+ BuiltInId::imageAtomicMaxExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01O00D00D(
+ BuiltInId::imageAtomicMaxExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Z00D00D(
+ BuiltInId::imageAtomicMaxExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01E10D00D(
+ BuiltInId::imageAtomicMaxExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01P10D00D(
+ BuiltInId::imageAtomicMaxExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01a10D00D(
+ BuiltInId::imageAtomicMaxExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01I10D00D(
+ BuiltInId::imageAtomicMaxExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01T10D00D(
+ BuiltInId::imageAtomicMaxExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01e10D00D(
+ BuiltInId::imageAtomicMaxExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01F10D00D00D(
+ BuiltInId::imageAtomicMaxExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Q10D00D00D(
+ BuiltInId::imageAtomicMaxExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01b10D00D00D(
+ BuiltInId::imageAtomicMaxExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01G20D00D00D(
+ BuiltInId::imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01R20D00D00D(
+ BuiltInId::imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01c20D00D00D(
+ BuiltInId::imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicAndExt_00z10D00E(
+ BuiltInId::imageAtomicAndExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01K10D00E(
+ BuiltInId::imageAtomicAndExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01V10D00E(
+ BuiltInId::imageAtomicAndExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01A20D00E(
+ BuiltInId::imageAtomicAndExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01L20D00E(
+ BuiltInId::imageAtomicAndExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01W20D00E(
+ BuiltInId::imageAtomicAndExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01C20D00E(
+ BuiltInId::imageAtomicAndExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01N20D00E(
+ BuiltInId::imageAtomicAndExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Y20D00E(
+ BuiltInId::imageAtomicAndExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01J00D00E(
+ BuiltInId::imageAtomicAndExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01U00D00E(
+ BuiltInId::imageAtomicAndExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01f00D00E(
+ BuiltInId::imageAtomicAndExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01B20D00E(
+ BuiltInId::imageAtomicAndExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01M20D00E(
+ BuiltInId::imageAtomicAndExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01X20D00E(
+ BuiltInId::imageAtomicAndExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01H20D00E(
+ BuiltInId::imageAtomicAndExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01S20D00E(
+ BuiltInId::imageAtomicAndExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01d20D00E(
+ BuiltInId::imageAtomicAndExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01D00D00E(
+ BuiltInId::imageAtomicAndExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01O00D00E(
+ BuiltInId::imageAtomicAndExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Z00D00E(
+ BuiltInId::imageAtomicAndExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01E10D00E(
+ BuiltInId::imageAtomicAndExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01P10D00E(
+ BuiltInId::imageAtomicAndExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01a10D00E(
+ BuiltInId::imageAtomicAndExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01I10D00E(
+ BuiltInId::imageAtomicAndExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01T10D00E(
+ BuiltInId::imageAtomicAndExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01e10D00E(
+ BuiltInId::imageAtomicAndExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01F10D00D00E(
+ BuiltInId::imageAtomicAndExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Q10D00D00E(
+ BuiltInId::imageAtomicAndExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01b10D00D00E(
+ BuiltInId::imageAtomicAndExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01G20D00D00E(
+ BuiltInId::imageAtomicAndExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01R20D00D00E(
+ BuiltInId::imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01c20D00D00E(
+ BuiltInId::imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_00z10D00D(
+ BuiltInId::imageAtomicAndExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01K10D00D(
+ BuiltInId::imageAtomicAndExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01V10D00D(
+ BuiltInId::imageAtomicAndExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01A20D00D(
+ BuiltInId::imageAtomicAndExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01L20D00D(
+ BuiltInId::imageAtomicAndExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01W20D00D(
+ BuiltInId::imageAtomicAndExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01C20D00D(
+ BuiltInId::imageAtomicAndExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01N20D00D(
+ BuiltInId::imageAtomicAndExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Y20D00D(
+ BuiltInId::imageAtomicAndExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01J00D00D(
+ BuiltInId::imageAtomicAndExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01U00D00D(
+ BuiltInId::imageAtomicAndExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01f00D00D(
+ BuiltInId::imageAtomicAndExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01B20D00D(
+ BuiltInId::imageAtomicAndExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01M20D00D(
+ BuiltInId::imageAtomicAndExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01X20D00D(
+ BuiltInId::imageAtomicAndExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01H20D00D(
+ BuiltInId::imageAtomicAndExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01S20D00D(
+ BuiltInId::imageAtomicAndExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01d20D00D(
+ BuiltInId::imageAtomicAndExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01D00D00D(
+ BuiltInId::imageAtomicAndExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01O00D00D(
+ BuiltInId::imageAtomicAndExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Z00D00D(
+ BuiltInId::imageAtomicAndExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01E10D00D(
+ BuiltInId::imageAtomicAndExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01P10D00D(
+ BuiltInId::imageAtomicAndExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01a10D00D(
+ BuiltInId::imageAtomicAndExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01I10D00D(
+ BuiltInId::imageAtomicAndExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01T10D00D(
+ BuiltInId::imageAtomicAndExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01e10D00D(
+ BuiltInId::imageAtomicAndExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01F10D00D00D(
+ BuiltInId::imageAtomicAndExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Q10D00D00D(
+ BuiltInId::imageAtomicAndExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01b10D00D00D(
+ BuiltInId::imageAtomicAndExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01G20D00D00D(
+ BuiltInId::imageAtomicAndExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01R20D00D00D(
+ BuiltInId::imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01c20D00D00D(
+ BuiltInId::imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicOrExt_00z10D00E(
+ BuiltInId::imageAtomicOrExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01K10D00E(
+ BuiltInId::imageAtomicOrExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01V10D00E(
+ BuiltInId::imageAtomicOrExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01A20D00E(
+ BuiltInId::imageAtomicOrExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01L20D00E(
+ BuiltInId::imageAtomicOrExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01W20D00E(
+ BuiltInId::imageAtomicOrExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01C20D00E(
+ BuiltInId::imageAtomicOrExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01N20D00E(
+ BuiltInId::imageAtomicOrExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Y20D00E(
+ BuiltInId::imageAtomicOrExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01J00D00E(
+ BuiltInId::imageAtomicOrExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01U00D00E(
+ BuiltInId::imageAtomicOrExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01f00D00E(
+ BuiltInId::imageAtomicOrExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01B20D00E(
+ BuiltInId::imageAtomicOrExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01M20D00E(
+ BuiltInId::imageAtomicOrExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01X20D00E(
+ BuiltInId::imageAtomicOrExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01H20D00E(
+ BuiltInId::imageAtomicOrExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01S20D00E(
+ BuiltInId::imageAtomicOrExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01d20D00E(
+ BuiltInId::imageAtomicOrExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01D00D00E(
+ BuiltInId::imageAtomicOrExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01O00D00E(
+ BuiltInId::imageAtomicOrExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Z00D00E(
+ BuiltInId::imageAtomicOrExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01E10D00E(
+ BuiltInId::imageAtomicOrExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01P10D00E(
+ BuiltInId::imageAtomicOrExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01a10D00E(
+ BuiltInId::imageAtomicOrExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01I10D00E(
+ BuiltInId::imageAtomicOrExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01T10D00E(
+ BuiltInId::imageAtomicOrExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01e10D00E(
+ BuiltInId::imageAtomicOrExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01F10D00D00E(
+ BuiltInId::imageAtomicOrExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Q10D00D00E(
+ BuiltInId::imageAtomicOrExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01b10D00D00E(
+ BuiltInId::imageAtomicOrExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01G20D00D00E(
+ BuiltInId::imageAtomicOrExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01R20D00D00E(
+ BuiltInId::imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01c20D00D00E(
+ BuiltInId::imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_00z10D00D(
+ BuiltInId::imageAtomicOrExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01K10D00D(
+ BuiltInId::imageAtomicOrExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01V10D00D(
+ BuiltInId::imageAtomicOrExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01A20D00D(
+ BuiltInId::imageAtomicOrExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01L20D00D(
+ BuiltInId::imageAtomicOrExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01W20D00D(
+ BuiltInId::imageAtomicOrExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01C20D00D(
+ BuiltInId::imageAtomicOrExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01N20D00D(
+ BuiltInId::imageAtomicOrExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Y20D00D(
+ BuiltInId::imageAtomicOrExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01J00D00D(
+ BuiltInId::imageAtomicOrExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01U00D00D(
+ BuiltInId::imageAtomicOrExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01f00D00D(
+ BuiltInId::imageAtomicOrExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01B20D00D(
+ BuiltInId::imageAtomicOrExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01M20D00D(
+ BuiltInId::imageAtomicOrExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01X20D00D(
+ BuiltInId::imageAtomicOrExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01H20D00D(
+ BuiltInId::imageAtomicOrExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01S20D00D(
+ BuiltInId::imageAtomicOrExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01d20D00D(
+ BuiltInId::imageAtomicOrExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01D00D00D(
+ BuiltInId::imageAtomicOrExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01O00D00D(
+ BuiltInId::imageAtomicOrExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Z00D00D(
+ BuiltInId::imageAtomicOrExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01E10D00D(
+ BuiltInId::imageAtomicOrExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01P10D00D(
+ BuiltInId::imageAtomicOrExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01a10D00D(
+ BuiltInId::imageAtomicOrExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01I10D00D(
+ BuiltInId::imageAtomicOrExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01T10D00D(
+ BuiltInId::imageAtomicOrExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01e10D00D(
+ BuiltInId::imageAtomicOrExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01F10D00D00D(
+ BuiltInId::imageAtomicOrExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Q10D00D00D(
+ BuiltInId::imageAtomicOrExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01b10D00D00D(
+ BuiltInId::imageAtomicOrExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01G20D00D00D(
+ BuiltInId::imageAtomicOrExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01R20D00D00D(
+ BuiltInId::imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01c20D00D00D(
+ BuiltInId::imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicXorExt_00z10D00E(
+ BuiltInId::imageAtomicXorExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01K10D00E(
+ BuiltInId::imageAtomicXorExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01V10D00E(
+ BuiltInId::imageAtomicXorExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01A20D00E(
+ BuiltInId::imageAtomicXorExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01L20D00E(
+ BuiltInId::imageAtomicXorExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01W20D00E(
+ BuiltInId::imageAtomicXorExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01C20D00E(
+ BuiltInId::imageAtomicXorExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01N20D00E(
+ BuiltInId::imageAtomicXorExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Y20D00E(
+ BuiltInId::imageAtomicXorExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01J00D00E(
+ BuiltInId::imageAtomicXorExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01U00D00E(
+ BuiltInId::imageAtomicXorExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01f00D00E(
+ BuiltInId::imageAtomicXorExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01B20D00E(
+ BuiltInId::imageAtomicXorExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01M20D00E(
+ BuiltInId::imageAtomicXorExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01X20D00E(
+ BuiltInId::imageAtomicXorExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01H20D00E(
+ BuiltInId::imageAtomicXorExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01S20D00E(
+ BuiltInId::imageAtomicXorExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01d20D00E(
+ BuiltInId::imageAtomicXorExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01D00D00E(
+ BuiltInId::imageAtomicXorExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01O00D00E(
+ BuiltInId::imageAtomicXorExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Z00D00E(
+ BuiltInId::imageAtomicXorExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01E10D00E(
+ BuiltInId::imageAtomicXorExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01P10D00E(
+ BuiltInId::imageAtomicXorExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01a10D00E(
+ BuiltInId::imageAtomicXorExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01I10D00E(
+ BuiltInId::imageAtomicXorExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01T10D00E(
+ BuiltInId::imageAtomicXorExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01e10D00E(
+ BuiltInId::imageAtomicXorExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01F10D00D00E(
+ BuiltInId::imageAtomicXorExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Q10D00D00E(
+ BuiltInId::imageAtomicXorExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01b10D00D00E(
+ BuiltInId::imageAtomicXorExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01G20D00D00E(
+ BuiltInId::imageAtomicXorExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01R20D00D00E(
+ BuiltInId::imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01c20D00D00E(
+ BuiltInId::imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_00z10D00D(
+ BuiltInId::imageAtomicXorExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01K10D00D(
+ BuiltInId::imageAtomicXorExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01V10D00D(
+ BuiltInId::imageAtomicXorExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01A20D00D(
+ BuiltInId::imageAtomicXorExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01L20D00D(
+ BuiltInId::imageAtomicXorExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01W20D00D(
+ BuiltInId::imageAtomicXorExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01C20D00D(
+ BuiltInId::imageAtomicXorExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01N20D00D(
+ BuiltInId::imageAtomicXorExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Y20D00D(
+ BuiltInId::imageAtomicXorExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01J00D00D(
+ BuiltInId::imageAtomicXorExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01U00D00D(
+ BuiltInId::imageAtomicXorExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01f00D00D(
+ BuiltInId::imageAtomicXorExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01B20D00D(
+ BuiltInId::imageAtomicXorExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01M20D00D(
+ BuiltInId::imageAtomicXorExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01X20D00D(
+ BuiltInId::imageAtomicXorExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01H20D00D(
+ BuiltInId::imageAtomicXorExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01S20D00D(
+ BuiltInId::imageAtomicXorExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01d20D00D(
+ BuiltInId::imageAtomicXorExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01D00D00D(
+ BuiltInId::imageAtomicXorExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01O00D00D(
+ BuiltInId::imageAtomicXorExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Z00D00D(
+ BuiltInId::imageAtomicXorExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01E10D00D(
+ BuiltInId::imageAtomicXorExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01P10D00D(
+ BuiltInId::imageAtomicXorExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01a10D00D(
+ BuiltInId::imageAtomicXorExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01I10D00D(
+ BuiltInId::imageAtomicXorExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01T10D00D(
+ BuiltInId::imageAtomicXorExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01e10D00D(
+ BuiltInId::imageAtomicXorExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01F10D00D00D(
+ BuiltInId::imageAtomicXorExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Q10D00D00D(
+ BuiltInId::imageAtomicXorExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01b10D00D00D(
+ BuiltInId::imageAtomicXorExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01G20D00D00D(
+ BuiltInId::imageAtomicXorExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01R20D00D00D(
+ BuiltInId::imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01c20D00D00D(
+ BuiltInId::imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_00z10D00E(
+ BuiltInId::imageAtomicExchangeExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01K10D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01V10D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01A20D00E(
+ BuiltInId::imageAtomicExchangeExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01L20D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01W20D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01C20D00E(
+ BuiltInId::imageAtomicExchangeExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01N20D00E(
+ BuiltInId::imageAtomicExchangeExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Y20D00E(
+ BuiltInId::imageAtomicExchangeExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01J00D00E(
+ BuiltInId::imageAtomicExchangeExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01U00D00E(
+ BuiltInId::imageAtomicExchangeExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01f00D00E(
+ BuiltInId::imageAtomicExchangeExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01B20D00E(
+ BuiltInId::imageAtomicExchangeExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01M20D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01X20D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01H20D00E(
+ BuiltInId::imageAtomicExchangeExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01S20D00E(
+ BuiltInId::imageAtomicExchangeExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01d20D00E(
+ BuiltInId::imageAtomicExchangeExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01D00D00E(
+ BuiltInId::imageAtomicExchangeExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01O00D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Z00D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01E10D00E(
+ BuiltInId::imageAtomicExchangeExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01P10D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01a10D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01I10D00E(
+ BuiltInId::imageAtomicExchangeExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01T10D00E(
+ BuiltInId::imageAtomicExchangeExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01e10D00E(
+ BuiltInId::imageAtomicExchangeExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01F10D00D00E(
+ BuiltInId::imageAtomicExchangeExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Q10D00D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01b10D00D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01G20D00D00E(
+ BuiltInId::imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01R20D00D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01c20D00D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_00z10D00D(
+ BuiltInId::imageAtomicExchangeExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01K10D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01V10D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01A20D00D(
+ BuiltInId::imageAtomicExchangeExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01L20D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01W20D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01C20D00D(
+ BuiltInId::imageAtomicExchangeExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01N20D00D(
+ BuiltInId::imageAtomicExchangeExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Y20D00D(
+ BuiltInId::imageAtomicExchangeExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01J00D00D(
+ BuiltInId::imageAtomicExchangeExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01U00D00D(
+ BuiltInId::imageAtomicExchangeExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01f00D00D(
+ BuiltInId::imageAtomicExchangeExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01B20D00D(
+ BuiltInId::imageAtomicExchangeExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01M20D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01X20D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01H20D00D(
+ BuiltInId::imageAtomicExchangeExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01S20D00D(
+ BuiltInId::imageAtomicExchangeExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01d20D00D(
+ BuiltInId::imageAtomicExchangeExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01D00D00D(
+ BuiltInId::imageAtomicExchangeExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01O00D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Z00D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01E10D00D(
+ BuiltInId::imageAtomicExchangeExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01P10D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01a10D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01I10D00D(
+ BuiltInId::imageAtomicExchangeExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01T10D00D(
+ BuiltInId::imageAtomicExchangeExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01e10D00D(
+ BuiltInId::imageAtomicExchangeExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01F10D00D00D(
+ BuiltInId::imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Q10D00D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01b10D00D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01G20D00D00D(
+ BuiltInId::imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01R20D00D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01c20D00D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_00z10D00B(
+ BuiltInId::imageAtomicExchangeExt_Image2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01K10D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01V10D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01A20D00B(
+ BuiltInId::imageAtomicExchangeExt_Image3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01L20D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01W20D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01C20D00B(
+ BuiltInId::imageAtomicExchangeExt_ImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01N20D00B(
+ BuiltInId::imageAtomicExchangeExt_IImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Y20D00B(
+ BuiltInId::imageAtomicExchangeExt_UImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01J00D00B(
+ BuiltInId::imageAtomicExchangeExt_ImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01U00D00B(
+ BuiltInId::imageAtomicExchangeExt_IImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01f00D00B(
+ BuiltInId::imageAtomicExchangeExt_UImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01B20D00B(
+ BuiltInId::imageAtomicExchangeExt_Image2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01M20D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01X20D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01H20D00B(
+ BuiltInId::imageAtomicExchangeExt_ImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01S20D00B(
+ BuiltInId::imageAtomicExchangeExt_IImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01d20D00B(
+ BuiltInId::imageAtomicExchangeExt_UImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01D00D00B(
+ BuiltInId::imageAtomicExchangeExt_Image1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01O00D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Z00D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01E10D00B(
+ BuiltInId::imageAtomicExchangeExt_Image1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01P10D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01a10D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01I10D00B(
+ BuiltInId::imageAtomicExchangeExt_ImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01T10D00B(
+ BuiltInId::imageAtomicExchangeExt_IImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01e10D00B(
+ BuiltInId::imageAtomicExchangeExt_UImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01F10D00D00B(
+ BuiltInId::imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Q10D00D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01b10D00D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01G20D00D00B(
+ BuiltInId::imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01R20D00D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01c20D00D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_00z10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01K10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01V10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01A20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01L20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01W20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01C20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_ImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01N20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Y20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01J00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_ImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01U00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01f00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01B20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01M20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01X20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01H20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_ImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01S20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01d20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01O00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Z00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01E10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01P10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01a10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01I10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_ImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01T10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01e10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01F10D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Q10D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01b10D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01G20D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01R20D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01c20D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_00z10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01K10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01V10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01A20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01L20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01W20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01C20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_ImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01N20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Y20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01J00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_ImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01U00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01f00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01B20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01M20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01X20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01H20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_ImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01S20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01d20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01O00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Z00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01E10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01P10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01a10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01I10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_ImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01T10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01e10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01F10D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Q10D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01b10D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01G20D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01R20D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01c20D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction pixelLocalLoadANGLE_01g(
+ BuiltInId::pixelLocalLoadANGLE_PixelLocalANGLE1,
+ BuiltInName::pixelLocalLoadANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01g30B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpPixelLocalLoadANGLE,
+ false);
+constexpr const TFunction pixelLocalLoadANGLE_01h(
+ BuiltInId::pixelLocalLoadANGLE_IPixelLocalANGLE1,
+ BuiltInName::pixelLocalLoadANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01h30D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpPixelLocalLoadANGLE,
+ false);
+constexpr const TFunction pixelLocalLoadANGLE_01i(
+ BuiltInId::pixelLocalLoadANGLE_UPixelLocalANGLE1,
+ BuiltInName::pixelLocalLoadANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01i30E,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpPixelLocalLoadANGLE,
+ false);
+constexpr const TFunction pixelLocalStoreANGLE_01g30B(
+ BuiltInId::pixelLocalStoreANGLE_PixelLocalANGLE1_Float4,
+ BuiltInName::pixelLocalStoreANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01g30B,
+ 2,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPixelLocalStoreANGLE,
+ false);
+constexpr const TFunction pixelLocalStoreANGLE_01h30D(
+ BuiltInId::pixelLocalStoreANGLE_IPixelLocalANGLE1_Int4,
+ BuiltInName::pixelLocalStoreANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01h30D,
+ 2,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPixelLocalStoreANGLE,
+ false);
+constexpr const TFunction pixelLocalStoreANGLE_01i30E(
+ BuiltInId::pixelLocalStoreANGLE_UPixelLocalANGLE1_UInt4,
+ BuiltInName::pixelLocalStoreANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01i30E,
+ 2,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPixelLocalStoreANGLE,
+ false);
+constexpr const TFunction beginInvocationInterlockNV_(
+ BuiltInId::beginInvocationInterlockNV,
+ BuiltInName::beginInvocationInterlockNV,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBeginInvocationInterlockNV,
+ false);
+constexpr const TFunction endInvocationInterlockNV_(
+ BuiltInId::endInvocationInterlockNV,
+ BuiltInName::endInvocationInterlockNV,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEndInvocationInterlockNV,
+ false);
+constexpr const TFunction beginFragmentShaderOrderingINTEL_(
+ BuiltInId::beginFragmentShaderOrderingINTEL,
+ BuiltInName::beginFragmentShaderOrderingINTEL,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBeginFragmentShaderOrderingINTEL,
+ false);
+constexpr const TFunction beginInvocationInterlockARB_(
+ BuiltInId::beginInvocationInterlockARB,
+ BuiltInName::beginInvocationInterlockARB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBeginInvocationInterlockARB,
+ false);
+constexpr const TFunction endInvocationInterlockARB_(
+ BuiltInId::endInvocationInterlockARB,
+ BuiltInName::endInvocationInterlockARB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEndInvocationInterlockARB,
+ false);
+constexpr const TFunction memoryBarrier_(BuiltInId::memoryBarrier,
+ BuiltInName::memoryBarrier,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMemoryBarrier,
+ false);
+constexpr const TFunction memoryBarrierAtomicCounter_(
+ BuiltInId::memoryBarrierAtomicCounter,
+ BuiltInName::memoryBarrierAtomicCounter,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMemoryBarrierAtomicCounter,
+ false);
+constexpr const TFunction memoryBarrierBuffer_(
+ BuiltInId::memoryBarrierBuffer,
+ BuiltInName::memoryBarrierBuffer,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMemoryBarrierBuffer,
+ false);
+constexpr const TFunction memoryBarrierImage_(
+ BuiltInId::memoryBarrierImage,
+ BuiltInName::memoryBarrierImage,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMemoryBarrierImage,
+ false);
+constexpr const TFunction barrier_(BuiltInId::barrier,
+ BuiltInName::barrier,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBarrier,
+ false);
+constexpr const TFunction memoryBarrierShared_(
+ BuiltInId::memoryBarrierShared,
+ BuiltInName::memoryBarrierShared,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMemoryBarrierShared,
+ false);
+constexpr const TFunction groupMemoryBarrier_(
+ BuiltInId::groupMemoryBarrier,
+ BuiltInName::groupMemoryBarrier,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpGroupMemoryBarrier,
+ false);
+constexpr const TFunction barrierTCS_(BuiltInId::barrierTCS,
+ BuiltInName::barrierTCS,
+ std::array<TExtension, 1u>{
+ {TExtension::EXT_tessellation_shader}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBarrierTCS,
+ false);
+constexpr const TFunction barrierTCSES3_2_(
+ BuiltInId::barrierTCSES3_2,
+ BuiltInName::barrierTCSES3_2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBarrierTCS,
+ false);
+constexpr const TFunction EmitVertex_(BuiltInId::EmitVertex,
+ BuiltInName::EmitVertex,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader,
+ TExtension::OES_geometry_shader}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEmitVertex,
+ false);
+constexpr const TFunction EmitVertexES3_2_(
+ BuiltInId::EmitVertexES3_2,
+ BuiltInName::EmitVertexES3_2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEmitVertex,
+ false);
+constexpr const TFunction EndPrimitive_(
+ BuiltInId::EndPrimitive,
+ BuiltInName::EndPrimitive,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEndPrimitive,
+ false);
+constexpr const TFunction EndPrimitiveES3_2_(
+ BuiltInId::EndPrimitiveES3_2,
+ BuiltInName::EndPrimitiveES3_2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEndPrimitive,
+ false);
+constexpr const TFunction subpassLoad_01j(
+ BuiltInId::subpassLoad_SubpassInput1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01j,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+constexpr const TFunction subpassLoad_01k(BuiltInId::subpassLoad_ISubpassInput1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01k,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+constexpr const TFunction subpassLoad_01l(BuiltInId::subpassLoad_USubpassInput1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01l,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+constexpr const TFunction subpassLoad_01m00D(
+ BuiltInId::subpassLoad_SubpassInputMS1_Int1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01m00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+constexpr const TFunction subpassLoad_01n00D(
+ BuiltInId::subpassLoad_ISubpassInputMS1_Int1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01n00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+constexpr const TFunction subpassLoad_01o00D(
+ BuiltInId::subpassLoad_USubpassInputMS1_Int1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01o00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+
+} // namespace Func
+
+namespace BuiltInArray
+{
+using namespace Func;
+using Rule = SymbolRule;
+
+// Rules used to initialize the mangled name array.
+constexpr SymbolRule kRules[] = {
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&radians_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&radians_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&radians_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&radians_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&degrees_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&degrees_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&degrees_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&degrees_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sin_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sin_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sin_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sin_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&cos_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&cos_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&cos_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&cos_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&tan_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&tan_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&tan_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&tan_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&asin_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&asin_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&asin_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&asin_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&acos_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&acos_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&acos_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&acos_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sinh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sinh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sinh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sinh_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&cosh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&cosh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&cosh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&cosh_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&tanh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&tanh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&tanh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&tanh_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&asinh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&asinh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&asinh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&asinh_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&acosh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&acosh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&acosh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&acosh_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&atanh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&atanh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&atanh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&atanh_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&pow_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&pow_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&pow_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&pow_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp2_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp2_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp2_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp2_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log2_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log2_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log2_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log2_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sqrt_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sqrt_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sqrt_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sqrt_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&inversesqrt_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&inversesqrt_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&inversesqrt_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&inversesqrt_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&abs_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&abs_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&abs_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&abs_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&abs_00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&abs_10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&abs_20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&abs_30D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sign_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sign_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sign_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sign_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sign_00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sign_10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sign_20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sign_30D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&floor_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&floor_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&floor_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&floor_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&trunc_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&trunc_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&trunc_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&trunc_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&round_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&round_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&round_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&round_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&roundEven_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&roundEven_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&roundEven_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&roundEven_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&ceil_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&ceil_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&ceil_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&ceil_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&fract_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&fract_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&fract_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&fract_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_10B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_20B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_30B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_10B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_20B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_30B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_10D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_20D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_30D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_30E30E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_10E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_20E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_30E00E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_10B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_20B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_30B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_10D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_20D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_30D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_30E30E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_10E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_20E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_30E00E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_00B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_10B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_20B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_30B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_10B10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_20B20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_30B30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_00D00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_10D00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_20D00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_30D00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_10D10D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_20D20D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_30D30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_00E00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_10E00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_20E00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_30E00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_10E10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_20E20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_30E30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_00B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_10B10B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_20B20B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_30B30B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_10B10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_20B20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_30B30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&mix_00B00B00F),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&mix_10B10B10F),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&mix_20B20B20F),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&mix_30B30B30F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_00D00D00F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_10D10D10F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_20D20D20F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_30D30D30F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_00E00E00F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_10E10E10F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_20E20E20F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_30E30E30F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_00F00F00F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_10F10F10F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_20F20F20F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_30F30F30F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_00B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_00B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_00B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_00B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_10B10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_20B20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_30B30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_00B00B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_00B00B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_00B00B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&modf_00B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&modf_10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&modf_20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&modf_30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isnan_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isnan_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isnan_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isnan_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isinf_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isinf_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isinf_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isinf_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToInt_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToInt_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToInt_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToInt_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToUint_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToUint_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToUint_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToUint_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&intBitsToFloat_00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&intBitsToFloat_10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&intBitsToFloat_20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&intBitsToFloat_30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&uintBitsToFloat_00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&uintBitsToFloat_10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&uintBitsToFloat_20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&uintBitsToFloat_30E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&fma_00B00B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(&fmaExt_00B00B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&fma_10B10B10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(&fmaExt_10B10B10B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&fma_20B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(&fmaExt_20B20B20B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&fma_30B30B30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(&fmaExt_30B30B30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&frexp_00B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&frexp_10B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&frexp_20B20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&frexp_30B30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&ldexp_00B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&ldexp_10B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&ldexp_20B20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&ldexp_30B30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&packSnorm2x16_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&packHalf2x16_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&unpackSnorm2x16_00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&unpackHalf2x16_00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&packUnorm2x16_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&unpackUnorm2x16_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&packUnorm4x8_30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&packSnorm4x8_30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&unpackUnorm4x8_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&unpackSnorm4x8_00E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&length_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&length_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&length_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&length_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&distance_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&distance_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&distance_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&distance_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&dot_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&dot_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&dot_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&dot_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&cross_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&normalize_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&normalize_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&normalize_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&normalize_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&faceforward_00B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&faceforward_10B10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&faceforward_20B20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&faceforward_30B30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&reflect_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&reflect_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&reflect_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&reflect_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&refract_00B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&refract_10B10B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&refract_20B20B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&refract_30B30B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&matrixCompMult_50B50B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&matrixCompMult_A0BA0B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&matrixCompMult_F0BF0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_90B90B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_60B60B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_D0BD0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_70B70B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_E0BE0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_B0BB0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_20B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_10B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_30B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_10B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_30B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_20B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_50B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_A0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_F0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_60B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_90B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_70B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_D0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_B0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_E0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&determinant_50B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&determinant_A0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&determinant_F0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&inverse_50B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&inverse_A0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&inverse_F0B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThan_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThan_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThan_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThanEqual_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThanEqual_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThanEqual_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThan_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThan_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThan_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThanEqual_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThanEqual_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThanEqual_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&equal_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&equal_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&equal_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_10F10F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_20F20F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_30F30F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&notEqual_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&notEqual_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&notEqual_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_10F10F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_20F20F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_30F30F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&any_10F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&any_20F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&any_30F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&all_10F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&all_20F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&all_30F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notFunc_10F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notFunc_20F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notFunc_30F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_30D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_00E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_10E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_20E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_30E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_00D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_10D10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_20D20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_30D30D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_00E00E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_10E10E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_20E20E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_30E30E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&uaddCarry_00E00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&uaddCarry_10E10E10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&uaddCarry_20E20E20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&uaddCarry_30E30E30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&usubBorrow_00E00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&usubBorrow_10E10E10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&usubBorrow_20E20E20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&usubBorrow_30E30E30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&umulExtended_00E00E00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&umulExtended_10E10E10E10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&umulExtended_20E20E20E20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&umulExtended_30E30E30E30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imulExtended_00D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imulExtended_10D10D10D10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imulExtended_20D20D20D20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imulExtended_30D30D30D30D),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&texture2D_00I10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&texture2DProj_00I20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&texture2DProj_00I30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&textureCube_00K20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_texture_3D)>(&texture3D_00J20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_texture_3D)>(&texture3DProj_00J30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shadow_samplers)>(&shadow2DEXT_00d20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shadow_samplers)>(
+ &shadow2DProjEXT_00d30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_EGL_image_external)>(&texture2D_00M10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(NV_EGL_stream_consumer_external)>(
+ &texture2D_00M10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_EGL_image_external)>(
+ &texture2DProj_00M20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(NV_EGL_stream_consumer_external)>(
+ &texture2DProj_00M20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_EGL_image_external)>(
+ &texture2DProj_00M30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(NV_EGL_stream_consumer_external)>(
+ &texture2DProj_00M30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(
+ &texture2DRect_00O10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(
+ &texture2DRectProj_00O20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(
+ &texture2DRectProj_00O30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DGradEXT_00I10B10B10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DProjGradEXT_00I20B10B10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DProjGradEXT_00I30B10B10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shader_texture_lod)>(
+ &textureCubeGradEXT_00K20B20B20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&textureVideoWEBGL_00y10B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&texture2D_00I10B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&texture2DProj_00I20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&texture2DProj_00I30B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&textureCube_00K20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_texture_3D)>(&texture3D_00J20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_texture_3D)>(
+ &texture3DProj_00J30B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_texture_3D)>(&texture3DLod_00J20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_texture_3D)>(&texture3DProjLod_00J30B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::VERTEX, 0>(&texture2DLod_00I10B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::VERTEX, 0>(&texture2DProjLod_00I20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::VERTEX, 0>(&texture2DProjLod_00I30B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::VERTEX, 0>(&textureCubeLod_00K20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DLodEXT_00I10B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DProjLodEXT_00I20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DProjLodEXT_00I30B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_shader_texture_lod)>(
+ &textureCubeLodEXT_00K20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00I10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00R10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00X10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00J20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00S20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00Y20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00K20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00T20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00Z20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00L20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00U20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00a20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00d20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00e30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00f30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texture_00k30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00k30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00k30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texture_00s30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00s30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00s30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texture_00x30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00x30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00x30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texture_00l30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00l30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00l30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &texture_00M10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&texture_00N10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(&texture_00O10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00y10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00I20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00R20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00X20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00I30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00R30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00X30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00J30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00S30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00Y30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00d30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &textureProj_00M20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &textureProj_00M30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&textureProj_00N20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&textureProj_00N30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(&textureProj_00O20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(&textureProj_00O30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00I10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00R10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00X10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00J20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00S20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00Y20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00K20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00T20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00Z20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00L20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00U20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00a20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00d20B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureLod_00k30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureLodExt_00k30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureLodExt_00k30B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureLod_00s30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureLodExt_00s30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureLodExt_00s30B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureLod_00x30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureLodExt_00x30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureLodExt_00x30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00I00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00R00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00X00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00J00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00S00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00Y00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00K00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00T00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00Z00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00L00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00U00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00a00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00d00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00e00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00f00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00k00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureSizeExt_00k00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureSizeExt_00k00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00s00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureSizeExt_00s00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureSizeExt_00s00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00x00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureSizeExt_00x00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureSizeExt_00x00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00l00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureSizeExt_00l00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureSizeExt_00l00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00j),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&textureSizeExt_00j),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&textureSizeExt_00j),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00r),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&textureSizeExt_00r),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&textureSizeExt_00r),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00w),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&textureSizeExt_00w),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&textureSizeExt_00w),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureSize_00P),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &textureSizeExt_00P),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureSize_00V),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &textureSizeExt_00V),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureSize_00b),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &textureSizeExt_00b),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00Q),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &textureSizeExt_00Q),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00W),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &textureSizeExt_00W),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00c),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &textureSizeExt_00c),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &textureSize_00M00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&textureSize_00N00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00I20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00R20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00X20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00I30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00R30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00X30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00J30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00S30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00Y30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00d30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00I10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00R10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00X10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00J20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00S20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00Y20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00L20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00U20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00a20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00j00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&texelFetchExt_00j00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&texelFetchExt_00j00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00r00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&texelFetchExt_00r00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&texelFetchExt_00r00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00w00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&texelFetchExt_00w00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&texelFetchExt_00w00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&texelFetch_00P10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &texelFetchExt_00P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&texelFetch_00V10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &texelFetchExt_00V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&texelFetch_00b10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &texelFetchExt_00b10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00Q20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &texelFetchExt_00Q20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &texelFetchExt_00W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00c20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &texelFetchExt_00c20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &texelFetch_00M10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&texelFetch_00N10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00I10B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00R10B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00X10B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00J20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00S20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00Y20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00K20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00T20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00Z20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00d20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00e30B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00L20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00U20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00a20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00f30B10B10B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGrad_00k30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGradExt_00k30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGradExt_00k30B20B20B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGrad_00s30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGradExt_00s30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGradExt_00s30B20B20B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGrad_00x30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGradExt_00x30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGradExt_00x30B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00I20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00R20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00X20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00I30B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00R30B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00X30B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00J30B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00S30B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00Y30B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00d30B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00I10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00R10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00X10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00J20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00S20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00Y20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00K20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00T20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00Z20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00L20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00U20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00a20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00I20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00R20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00X20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00I30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00R30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00X30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00J30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00S30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00Y30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00d20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00e30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00d30B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&texture_00k30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00k30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00k30B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&texture_00s30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00s30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00s30B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&texture_00x30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00x30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00x30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &texture_00M10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &textureProj_00M20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &textureProj_00M30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(EXT_YUV_target)>(&texture_00N10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(EXT_YUV_target)>(&textureProj_00N20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(EXT_YUV_target)>(&textureProj_00N30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00I10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00R10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00X10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00J20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00S20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00Y20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00d20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00L20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00U20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00a20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00I20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00R20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00X20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00I30B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00R30B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00X30B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00J30B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00S30B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00Y30B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00d30B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00I10B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00R10B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00X10B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00J20B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00S20B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00Y20B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00d20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00L20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00U20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00a20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00I20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00R20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00X20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00I30B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00R30B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00X30B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00J30B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00S30B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00Y30B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00d30B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00I10D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00R10D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00X10D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00J20D00D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00S20D00D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00Y20D00D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00L20D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00U20D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00a20D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00I10B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00R10B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00X10B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00J20B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00S20B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00Y20B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00d20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00L20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00U20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00a20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00f30B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00I20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00R20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00X20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00I30B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00R30B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00X30B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00J30B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00S30B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00Y30B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00d30B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00I10B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00R10B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00X10B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00J20B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00S20B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00Y20B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00d20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00L20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00U20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00a20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00I20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00R20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00X20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00I30B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00R30B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00X30B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00J30B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00S30B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00Y30B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00d30B10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00I10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00R10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00X10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00I10B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00R10B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00X10B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00L20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00U20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00a20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00L20B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00U20B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00a20B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00K20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00T20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00Z20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00K20B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00T20B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00Z20B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00k30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00k30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00k30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00s30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00s30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00s30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00x30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00x30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00x30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00k30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00k30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00k30B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00s30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00s30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00s30B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00x30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00x30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00x30B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00l30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00l30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00l30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00d10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00d10B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00f20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00f20B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00e20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00e20B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00I10B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00R10B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00X10B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00L20B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00U20B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00a20B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00d10B00B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00f20B00B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00I10B10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00R10B10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00X10B10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00L20B10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00U20B10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00a20B10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00I10B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00I10B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00R10B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00R10B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00X10B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00X10B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00L20B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00L20B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00U20B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00U20B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00a20B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00a20B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00d10B00B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00d10B00B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00f20B00B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00f20B00B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00I10B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00I10B10Dx400D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00R10B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00R10B10Dx400D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00X10B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00X10B10Dx400D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00L20B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00L20B10Dx400D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00U20B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00U20B10Dx400D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00a20B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00a20B10Dx400D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&rgb_2_yuv_20B00H),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&yuv_2_rgb_20B00H),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdx_00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdxExt_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdx_10B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdxExt_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdx_20B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdxExt_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdx_30B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdxExt_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdy_00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdyExt_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdy_10B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdyExt_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdy_20B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdyExt_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdy_30B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdyExt_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&fwidth_00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(
+ &fwidthExt_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&fwidth_10B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(
+ &fwidthExt_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&fwidth_20B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(
+ &fwidthExt_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&fwidth_30B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(
+ &fwidthExt_30B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtCentroid_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtCentroidExt_00B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtCentroid_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtCentroidExt_10B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtCentroid_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtCentroidExt_20B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtCentroid_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtCentroidExt_30B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtSample_00B00D),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtSampleExt_00B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtSample_10B00D),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtSampleExt_10B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtSample_20B00D),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtSampleExt_20B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtSample_30B00D),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtSampleExt_30B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtOffset_00B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtOffsetExt_00B10B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtOffset_10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtOffsetExt_10B10B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtOffset_20B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtOffsetExt_20B10B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtOffset_30B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtOffsetExt_30B10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicCounter_00G),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicCounterIncrement_00G),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicCounterDecrement_00G),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicAdd_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicAdd_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicMin_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicMin_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicMax_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicMax_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicAnd_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicAnd_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicOr_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicOr_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicXor_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicXor_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicExchange_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicExchange_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicCompSwap_00E00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicCompSwap_00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_00z),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01K),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01V),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01A),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01L),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01W),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01M),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01X),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01C),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01N),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01Y),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01H),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageSizeExt_01H),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageSizeExt_01H),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01S),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageSizeExt_01S),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageSizeExt_01S),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01d),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageSizeExt_01d),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageSizeExt_01d),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01J),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageSizeExt_01J),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageSizeExt_01J),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01U),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageSizeExt_01U),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageSizeExt_01U),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01f),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageSizeExt_01f),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageSizeExt_01f),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_00z10D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01K10D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01V10D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01A20D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01L20D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01W20D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01B20D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01M20D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01X20D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01C20D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01N20D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01Y20D30E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01H20D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageStoreExt_01H20D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageStoreExt_01H20D30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01S20D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageStoreExt_01S20D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageStoreExt_01S20D30D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01d20D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageStoreExt_01d20D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageStoreExt_01d20D30E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01J00D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(
+ &imageStoreExt_01J00D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(
+ &imageStoreExt_01J00D30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01U00D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(
+ &imageStoreExt_01U00D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(
+ &imageStoreExt_01U00D30D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01f00D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(
+ &imageStoreExt_01f00D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(
+ &imageStoreExt_01f00D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_00z10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01K10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01V10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01A20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01L20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01W20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01B20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01M20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01X20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01C20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01N20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01Y20D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01H20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageLoadExt_01H20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageLoadExt_01H20D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01S20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageLoadExt_01S20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageLoadExt_01S20D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01d20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageLoadExt_01d20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageLoadExt_01d20D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01J00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageLoadExt_01J00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageLoadExt_01J00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01U00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageLoadExt_01U00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageLoadExt_01U00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01f00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageLoadExt_01f00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageLoadExt_01f00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_00z10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_00z10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01K10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01K10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01V10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01V10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01A20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01A20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01L20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01L20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01W20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01W20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01C20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01C20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01N20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01N20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Y20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Y20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01J00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01J00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01U00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01U00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01f00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01f00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01B20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01B20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01M20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01M20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01X20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01X20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01H20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01H20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01S20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01S20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01d20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01d20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01O00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01O00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Z00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Z00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01E10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01E10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01P10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01P10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01a10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01a10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01I10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01I10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01T10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01T10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01e10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01e10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01F10D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01F10D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Q10D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Q10D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01b10D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01b10D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01G20D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01G20D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01R20D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01R20D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01c20D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01c20D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_00z10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_00z10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01K10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01K10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01V10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01V10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01A20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01A20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01L20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01L20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01W20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01W20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01C20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01C20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01N20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01N20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Y20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Y20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01J00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01J00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01U00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01U00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01f00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01f00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01B20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01B20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01M20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01M20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01X20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01X20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01H20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01H20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01S20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01S20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01d20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01d20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01O00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01O00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Z00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Z00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01E10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01E10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01P10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01P10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01a10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01a10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01I10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01I10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01T10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01T10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01e10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01e10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01F10D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01F10D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Q10D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Q10D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01b10D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01b10D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01G20D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01G20D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01R20D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01R20D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01c20D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01c20D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_00z10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_00z10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01K10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01K10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01V10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01V10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01A20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01A20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01L20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01L20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01W20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01W20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01C20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01C20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01N20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01N20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Y20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Y20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01J00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01J00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01U00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01U00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01f00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01f00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01B20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01B20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01M20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01M20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01X20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01X20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01H20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01H20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01S20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01S20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01d20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01d20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01O00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01O00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Z00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Z00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01E10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01E10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01P10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01P10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01a10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01a10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01I10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01I10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01T10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01T10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01e10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01e10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01F10D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01F10D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Q10D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Q10D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01b10D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01b10D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01G20D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01G20D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01R20D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01R20D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01c20D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01c20D00D00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalLoadANGLE_01g),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalLoadANGLE_01h),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalLoadANGLE_01i),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalStoreANGLE_01g30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalStoreANGLE_01h30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalStoreANGLE_01i30E),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(
+ &beginInvocationInterlockNV_),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&endInvocationInterlockNV_),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(
+ &beginFragmentShaderOrderingINTEL_),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(
+ &beginInvocationInterlockARB_),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(
+ &endInvocationInterlockARB_),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&memoryBarrier_),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&memoryBarrierAtomicCounter_),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&memoryBarrierBuffer_),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&memoryBarrierImage_),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&barrier_),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&barrierTCSES3_2_),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &barrierTCS_),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&memoryBarrierShared_),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&groupMemoryBarrier_),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY, 0>(&EmitVertexES3_2_),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY, EXT_INDEX(EXT_geometry_shader)>(&EmitVertex_),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY, EXT_INDEX(OES_geometry_shader)>(&EmitVertex_),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY, 0>(&EndPrimitiveES3_2_),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY, EXT_INDEX(EXT_geometry_shader)>(&EndPrimitive_),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY, EXT_INDEX(OES_geometry_shader)>(&EndPrimitive_),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01j),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01k),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01l),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01m00D),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01n00D),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01o00D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_DepthRangeParameters),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_DepthRange),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&BuiltInVariable::kgl_NumSamplesES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_sample_variables)>(
+ &BuiltInVariable::kgl_NumSamples),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexAttribs),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexUniformVectors),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexTextureImageUnits),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxCombinedTextureImageUnits),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxTextureImageUnits),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxFragmentUniformVectors),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&TableBase::m_gl_MaxVaryingVectors),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxDrawBuffers),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, EXT_INDEX(EXT_blend_func_extended)>(
+ &TableBase::m_gl_MaxDualSourceDrawBuffersEXT),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexOutputVectors),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&TableBase::m_gl_MaxFragmentInputVectors),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&TableBase::m_gl_MinProgramTexelOffset),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&TableBase::m_gl_MaxProgramTexelOffset),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxImageUnits),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexImageUniforms),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxFragmentImageUniforms),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeImageUniforms),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxCombinedImageUniforms),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxCombinedShaderOutputResources),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeWorkGroupCount),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeWorkGroupSize),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeUniformComponents),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeTextureImageUnits),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeAtomicCounters),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexAtomicCounters),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxFragmentAtomicCounters),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxCombinedAtomicCounters),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxAtomicCounterBindings),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxFragmentAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxCombinedAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxAtomicCounterBufferSize),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryInputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryInputComponents),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryInputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryOutputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryOutputComponents),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryOutputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryImageUniformsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryImageUniforms),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryImageUniforms),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryTextureImageUnitsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryTextureImageUnits),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryTextureImageUnits),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryOutputVerticesES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryOutputVertices),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryOutputVertices),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxGeometryTotalOutputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryTotalOutputComponents),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryTotalOutputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryUniformComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryUniformComponents),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryUniformComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryAtomicCountersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryAtomicCounters),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryAtomicCounters),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxGeometryAtomicCounterBuffersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxTessControlInputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlInputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessControlOutputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlOutputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessControlTextureImageUnitsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlTextureImageUnits),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessControlUniformComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlUniformComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessControlTotalOutputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlTotalOutputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxTessControlImageUniformsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlImageUniforms),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxTessControlAtomicCountersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlAtomicCounters),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessControlAtomicCounterBuffersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxTessPatchComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessPatchComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxPatchVerticesES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxPatchVertices),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxTessGenLevelES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessGenLevel),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationInputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationInputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationOutputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationOutputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationTextureImageUnitsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationTextureImageUnits),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationUniformComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationUniformComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationImageUniformsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationImageUniforms),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationAtomicCountersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationAtomicCounters),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationAtomicCounterBuffersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxSamplesES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_sample_variables)>(
+ &TableBase::m_gl_MaxSamples),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, EXT_INDEX(APPLE_clip_distance)>(
+ &TableBase::m_gl_MaxClipDistancesAPPLE),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_clip_cull_distance)>(
+ &TableBase::m_gl_MaxCullDistancesEXT),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_clip_cull_distance)>(
+ &TableBase::m_gl_MaxCombinedClipAndCullDistancesEXT),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_FragCoord),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_FragCoord300),
+ Rule::Get<Spec::ESSL, 0, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_FrontFacing),
+ Rule::Get<Spec::ESSL, 0, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_PointCoord),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_FragColor),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&TableBase::m_gl_FragData),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_FragDepth),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_HelperInvocation),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_blend_func_extended)>(
+ &BuiltInVariable::kgl_SecondaryFragColorEXT),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_blend_func_extended)>(
+ &TableBase::m_gl_SecondaryFragDataEXT),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_frag_depth)>(
+ &TableBase::m_gl_FragDepthEXT),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_shader_framebuffer_fetch)>(
+ &TableBase::m_gl_LastFragData),
+ Rule::Get<Spec::ESSL,
+ 100,
+ Shader::FRAGMENT,
+ EXT_INDEX(EXT_shader_framebuffer_fetch_non_coherent)>(&TableBase::m_gl_LastFragData),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(NV_shader_framebuffer_fetch)>(
+ &TableBase::m_gl_LastFragDataNV),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(NV_shader_framebuffer_fetch)>(
+ &BuiltInVariable::kgl_LastFragColor),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(ARM_shader_framebuffer_fetch)>(
+ &BuiltInVariable::kgl_LastFragColorARM),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_PrimitiveIDES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&BuiltInVariable::kgl_PrimitiveIDGSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &BuiltInVariable::kgl_PrimitiveIDTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(
+ &BuiltInVariable::kgl_PrimitiveIDTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveID),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveID),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDGS),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDGS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDTES),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_LayerES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&BuiltInVariable::kgl_LayerGSES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_Layer),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_Layer),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_LayerGS),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_LayerGS),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_SampleIDES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_sample_variables)>(
+ &BuiltInVariable::kgl_SampleID),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_SamplePositionES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_sample_variables)>(
+ &BuiltInVariable::kgl_SamplePosition),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&TableBase::m_gl_SampleMaskInES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_sample_variables)>(
+ &TableBase::m_gl_SampleMaskIn),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&TableBase::m_gl_SampleMaskES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_sample_variables)>(
+ &TableBase::m_gl_SampleMask),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(EXT_clip_cull_distance)>(
+ &TableBase::m_gl_CullDistance),
+ Rule::Get<Spec::ESSL, 300, Shader::VERTEX, EXT_INDEX(EXT_clip_cull_distance)>(
+ &TableBase::m_gl_CullDistanceEXT),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(EXT_clip_cull_distance)>(
+ &TableBase::m_gl_ClipDistance),
+ Rule::Get<Spec::ESSL, 0, Shader::VERTEX, EXT_INDEX(APPLE_clip_distance)>(
+ &TableBase::m_gl_ClipDistanceAPPLE),
+ Rule::Get<Spec::ESSL, 0, Shader::VERTEX, 0>(&BuiltInVariable::kgl_Position),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&TableBase::m_gl_PositionGSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&TableBase::m_gl_PositionTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(&TableBase::m_gl_PositionTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_PositionGS),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_PositionGS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_PositionTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_PositionTES),
+ Rule::Get<Spec::ESSL, 100, Shader::VERTEX, 0>(&BuiltInVariable::kgl_PointSize),
+ Rule::Get<Spec::ESSL, 300, Shader::VERTEX, 0>(&BuiltInVariable::kgl_PointSize300),
+ Rule::Get<Spec::ESSL, 300, Shader::VERTEX, 0>(&BuiltInVariable::kgl_InstanceID),
+ Rule::Get<Spec::ESSL, 300, Shader::VERTEX, 0>(&BuiltInVariable::kgl_VertexID),
+ Rule::Get<Spec::ESSL, 0, Shader::VERTEX, EXT_INDEX(ANGLE_multi_draw)>(
+ &BuiltInVariable::kgl_DrawID),
+ Rule::Get<Spec::ESSL,
+ 300,
+ Shader::VERTEX,
+ EXT_INDEX(ANGLE_base_vertex_base_instance_shader_builtin)>(
+ &BuiltInVariable::kgl_BaseVertex),
+ Rule::Get<Spec::ESSL,
+ 300,
+ Shader::VERTEX,
+ EXT_INDEX(ANGLE_base_vertex_base_instance_shader_builtin)>(
+ &BuiltInVariable::kgl_BaseInstance),
+ Rule::Get<Spec::ESSL,
+ 0,
+ Shader::VERTEX,
+ EXT_INDEX(ANGLE_base_vertex_base_instance_shader_builtin)>(
+ &BuiltInVariable::kangle_BaseVertex),
+ Rule::Get<Spec::ESSL,
+ 0,
+ Shader::VERTEX,
+ EXT_INDEX(ANGLE_base_vertex_base_instance_shader_builtin)>(
+ &BuiltInVariable::kangle_BaseInstance),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_NumWorkGroups),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_WorkGroupSize),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_WorkGroupID),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_LocalInvocationID),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_GlobalInvocationID),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_LocalInvocationIndex),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&BuiltInVariable::kgl_PrimitiveIDInES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDIn),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDIn),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&BuiltInVariable::kgl_InvocationIDES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &BuiltInVariable::kgl_InvocationIDTCSES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_InvocationID),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_InvocationID),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &BuiltInVariable::kgl_InvocationIDTCS),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&TableBase::m_gl_PerVertexES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&TableBase::m_gl_PerVertexTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(&TableBase::m_gl_PerVertexTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_PerVertex),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_PerVertex),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_PerVertexTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_PerVertexTES),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&TableBase::m_gl_inES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&TableBase::m_gl_inTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(&TableBase::m_gl_inTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_in),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_in),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_inTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_inTES),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &BuiltInVariable::kgl_PatchVerticesInTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(
+ &BuiltInVariable::kgl_PatchVerticesInTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &BuiltInVariable::kgl_PatchVerticesInTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &BuiltInVariable::kgl_PatchVerticesInTES),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &TableBase::m_gl_TessLevelOuterTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(
+ &TableBase::m_gl_TessLevelOuterTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_TessLevelOuterTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_TessLevelOuterTES),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &TableBase::m_gl_TessLevelInnerTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(
+ &TableBase::m_gl_TessLevelInnerTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_TessLevelInnerTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_TessLevelInnerTES),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&TableBase::m_gl_outTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(&TableBase::m_gl_outTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_outTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_outTES),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&TableBase::m_gl_BoundingBoxTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_BoundingBoxTCS),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &TableBase::m_gl_BoundingBoxEXTTCSES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_BoundingBoxEXTTCS),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &TableBase::m_gl_BoundingBoxOESTCSES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_BoundingBoxOESTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, 0>(&BuiltInVariable::kgl_TessCoord),
+ Rule::Get<Spec::ESSL, 300, Shader::NOT_COMPUTE, EXT_INDEX(OVR_multiview)>(
+ &BuiltInVariable::kgl_ViewID_OVR)};
+
+// Flat array of all mangled names.
+constexpr const char *kMangledNames[] = {"radians(00B",
+ "radians(10B",
+ "radians(20B",
+ "radians(30B",
+ "degrees(00B",
+ "degrees(10B",
+ "degrees(20B",
+ "degrees(30B",
+ "sin(00B",
+ "sin(10B",
+ "sin(20B",
+ "sin(30B",
+ "cos(00B",
+ "cos(10B",
+ "cos(20B",
+ "cos(30B",
+ "tan(00B",
+ "tan(10B",
+ "tan(20B",
+ "tan(30B",
+ "asin(00B",
+ "asin(10B",
+ "asin(20B",
+ "asin(30B",
+ "acos(00B",
+ "acos(10B",
+ "acos(20B",
+ "acos(30B",
+ "atan(00B00B",
+ "atan(10B10B",
+ "atan(20B20B",
+ "atan(30B30B",
+ "atan(00B",
+ "atan(10B",
+ "atan(20B",
+ "atan(30B",
+ "sinh(00B",
+ "sinh(10B",
+ "sinh(20B",
+ "sinh(30B",
+ "cosh(00B",
+ "cosh(10B",
+ "cosh(20B",
+ "cosh(30B",
+ "tanh(00B",
+ "tanh(10B",
+ "tanh(20B",
+ "tanh(30B",
+ "asinh(00B",
+ "asinh(10B",
+ "asinh(20B",
+ "asinh(30B",
+ "acosh(00B",
+ "acosh(10B",
+ "acosh(20B",
+ "acosh(30B",
+ "atanh(00B",
+ "atanh(10B",
+ "atanh(20B",
+ "atanh(30B",
+ "pow(00B00B",
+ "pow(10B10B",
+ "pow(20B20B",
+ "pow(30B30B",
+ "exp(00B",
+ "exp(10B",
+ "exp(20B",
+ "exp(30B",
+ "log(00B",
+ "log(10B",
+ "log(20B",
+ "log(30B",
+ "exp2(00B",
+ "exp2(10B",
+ "exp2(20B",
+ "exp2(30B",
+ "log2(00B",
+ "log2(10B",
+ "log2(20B",
+ "log2(30B",
+ "sqrt(00B",
+ "sqrt(10B",
+ "sqrt(20B",
+ "sqrt(30B",
+ "inversesqrt(00B",
+ "inversesqrt(10B",
+ "inversesqrt(20B",
+ "inversesqrt(30B",
+ "abs(00B",
+ "abs(10B",
+ "abs(20B",
+ "abs(30B",
+ "abs(00D",
+ "abs(10D",
+ "abs(20D",
+ "abs(30D",
+ "sign(00B",
+ "sign(10B",
+ "sign(20B",
+ "sign(30B",
+ "sign(00D",
+ "sign(10D",
+ "sign(20D",
+ "sign(30D",
+ "floor(00B",
+ "floor(10B",
+ "floor(20B",
+ "floor(30B",
+ "trunc(00B",
+ "trunc(10B",
+ "trunc(20B",
+ "trunc(30B",
+ "round(00B",
+ "round(10B",
+ "round(20B",
+ "round(30B",
+ "roundEven(00B",
+ "roundEven(10B",
+ "roundEven(20B",
+ "roundEven(30B",
+ "ceil(00B",
+ "ceil(10B",
+ "ceil(20B",
+ "ceil(30B",
+ "fract(00B",
+ "fract(10B",
+ "fract(20B",
+ "fract(30B",
+ "mod(00B00B",
+ "mod(10B00B",
+ "mod(20B00B",
+ "mod(30B00B",
+ "mod(10B10B",
+ "mod(20B20B",
+ "mod(30B30B",
+ "min(00B00B",
+ "min(10B00B",
+ "min(20B00B",
+ "min(30B00B",
+ "min(10B10B",
+ "min(20B20B",
+ "min(30B30B",
+ "min(00D00D",
+ "min(10D10D",
+ "min(20D20D",
+ "min(30D30D",
+ "min(10D00D",
+ "min(20D00D",
+ "min(30D00D",
+ "min(00E00E",
+ "min(10E10E",
+ "min(20E20E",
+ "min(30E30E",
+ "min(10E00E",
+ "min(20E00E",
+ "min(30E00E",
+ "max(00B00B",
+ "max(10B00B",
+ "max(20B00B",
+ "max(30B00B",
+ "max(10B10B",
+ "max(20B20B",
+ "max(30B30B",
+ "max(00D00D",
+ "max(10D10D",
+ "max(20D20D",
+ "max(30D30D",
+ "max(10D00D",
+ "max(20D00D",
+ "max(30D00D",
+ "max(00E00E",
+ "max(10E10E",
+ "max(20E20E",
+ "max(30E30E",
+ "max(10E00E",
+ "max(20E00E",
+ "max(30E00E",
+ "clamp(00B00B00B",
+ "clamp(10B00B00B",
+ "clamp(20B00B00B",
+ "clamp(30B00B00B",
+ "clamp(10B10B10B",
+ "clamp(20B20B20B",
+ "clamp(30B30B30B",
+ "clamp(00D00D00D",
+ "clamp(10D00D00D",
+ "clamp(20D00D00D",
+ "clamp(30D00D00D",
+ "clamp(10D10D10D",
+ "clamp(20D20D20D",
+ "clamp(30D30D30D",
+ "clamp(00E00E00E",
+ "clamp(10E00E00E",
+ "clamp(20E00E00E",
+ "clamp(30E00E00E",
+ "clamp(10E10E10E",
+ "clamp(20E20E20E",
+ "clamp(30E30E30E",
+ "mix(00B00B00B",
+ "mix(10B10B00B",
+ "mix(20B20B00B",
+ "mix(30B30B00B",
+ "mix(10B10B10B",
+ "mix(20B20B20B",
+ "mix(30B30B30B",
+ "mix(00B00B00F",
+ "mix(10B10B10F",
+ "mix(20B20B20F",
+ "mix(30B30B30F",
+ "mix(00D00D00F",
+ "mix(10D10D10F",
+ "mix(20D20D20F",
+ "mix(30D30D30F",
+ "mix(00E00E00F",
+ "mix(10E10E10F",
+ "mix(20E20E20F",
+ "mix(30E30E30F",
+ "mix(00F00F00F",
+ "mix(10F10F10F",
+ "mix(20F20F20F",
+ "mix(30F30F30F",
+ "step(00B00B",
+ "step(10B10B",
+ "step(20B20B",
+ "step(30B30B",
+ "step(00B10B",
+ "step(00B20B",
+ "step(00B30B",
+ "smoothstep(00B00B00B",
+ "smoothstep(10B10B10B",
+ "smoothstep(20B20B20B",
+ "smoothstep(30B30B30B",
+ "smoothstep(00B00B10B",
+ "smoothstep(00B00B20B",
+ "smoothstep(00B00B30B",
+ "modf(00B00B",
+ "modf(10B10B",
+ "modf(20B20B",
+ "modf(30B30B",
+ "isnan(00B",
+ "isnan(10B",
+ "isnan(20B",
+ "isnan(30B",
+ "isinf(00B",
+ "isinf(10B",
+ "isinf(20B",
+ "isinf(30B",
+ "floatBitsToInt(00B",
+ "floatBitsToInt(10B",
+ "floatBitsToInt(20B",
+ "floatBitsToInt(30B",
+ "floatBitsToUint(00B",
+ "floatBitsToUint(10B",
+ "floatBitsToUint(20B",
+ "floatBitsToUint(30B",
+ "intBitsToFloat(00D",
+ "intBitsToFloat(10D",
+ "intBitsToFloat(20D",
+ "intBitsToFloat(30D",
+ "uintBitsToFloat(00E",
+ "uintBitsToFloat(10E",
+ "uintBitsToFloat(20E",
+ "uintBitsToFloat(30E",
+ "fma(00B00B00B",
+ "fma(10B10B10B",
+ "fma(20B20B20B",
+ "fma(30B30B30B",
+ "frexp(00B00D",
+ "frexp(10B10D",
+ "frexp(20B20D",
+ "frexp(30B30D",
+ "ldexp(00B00D",
+ "ldexp(10B10D",
+ "ldexp(20B20D",
+ "ldexp(30B30D",
+ "packSnorm2x16(10B",
+ "packHalf2x16(10B",
+ "unpackSnorm2x16(00E",
+ "unpackHalf2x16(00E",
+ "packUnorm2x16(10B",
+ "unpackUnorm2x16(00E",
+ "packUnorm4x8(30B",
+ "packSnorm4x8(30B",
+ "unpackUnorm4x8(00E",
+ "unpackSnorm4x8(00E",
+ "length(00B",
+ "length(10B",
+ "length(20B",
+ "length(30B",
+ "distance(00B00B",
+ "distance(10B10B",
+ "distance(20B20B",
+ "distance(30B30B",
+ "dot(00B00B",
+ "dot(10B10B",
+ "dot(20B20B",
+ "dot(30B30B",
+ "cross(20B20B",
+ "normalize(00B",
+ "normalize(10B",
+ "normalize(20B",
+ "normalize(30B",
+ "faceforward(00B00B00B",
+ "faceforward(10B10B10B",
+ "faceforward(20B20B20B",
+ "faceforward(30B30B30B",
+ "reflect(00B00B",
+ "reflect(10B10B",
+ "reflect(20B20B",
+ "reflect(30B30B",
+ "refract(00B00B00B",
+ "refract(10B10B00B",
+ "refract(20B20B00B",
+ "refract(30B30B00B",
+ "matrixCompMult(50B50B",
+ "matrixCompMult(A0BA0B",
+ "matrixCompMult(F0BF0B",
+ "matrixCompMult(90B90B",
+ "matrixCompMult(60B60B",
+ "matrixCompMult(D0BD0B",
+ "matrixCompMult(70B70B",
+ "matrixCompMult(E0BE0B",
+ "matrixCompMult(B0BB0B",
+ "outerProduct(10B10B",
+ "outerProduct(20B20B",
+ "outerProduct(30B30B",
+ "outerProduct(20B10B",
+ "outerProduct(10B20B",
+ "outerProduct(30B10B",
+ "outerProduct(10B30B",
+ "outerProduct(30B20B",
+ "outerProduct(20B30B",
+ "transpose(50B",
+ "transpose(A0B",
+ "transpose(F0B",
+ "transpose(60B",
+ "transpose(90B",
+ "transpose(70B",
+ "transpose(D0B",
+ "transpose(B0B",
+ "transpose(E0B",
+ "determinant(50B",
+ "determinant(A0B",
+ "determinant(F0B",
+ "inverse(50B",
+ "inverse(A0B",
+ "inverse(F0B",
+ "lessThan(10B10B",
+ "lessThan(20B20B",
+ "lessThan(30B30B",
+ "lessThan(10D10D",
+ "lessThan(20D20D",
+ "lessThan(30D30D",
+ "lessThan(10E10E",
+ "lessThan(20E20E",
+ "lessThan(30E30E",
+ "lessThanEqual(10B10B",
+ "lessThanEqual(20B20B",
+ "lessThanEqual(30B30B",
+ "lessThanEqual(10D10D",
+ "lessThanEqual(20D20D",
+ "lessThanEqual(30D30D",
+ "lessThanEqual(10E10E",
+ "lessThanEqual(20E20E",
+ "lessThanEqual(30E30E",
+ "greaterThan(10B10B",
+ "greaterThan(20B20B",
+ "greaterThan(30B30B",
+ "greaterThan(10D10D",
+ "greaterThan(20D20D",
+ "greaterThan(30D30D",
+ "greaterThan(10E10E",
+ "greaterThan(20E20E",
+ "greaterThan(30E30E",
+ "greaterThanEqual(10B10B",
+ "greaterThanEqual(20B20B",
+ "greaterThanEqual(30B30B",
+ "greaterThanEqual(10D10D",
+ "greaterThanEqual(20D20D",
+ "greaterThanEqual(30D30D",
+ "greaterThanEqual(10E10E",
+ "greaterThanEqual(20E20E",
+ "greaterThanEqual(30E30E",
+ "equal(10B10B",
+ "equal(20B20B",
+ "equal(30B30B",
+ "equal(10D10D",
+ "equal(20D20D",
+ "equal(30D30D",
+ "equal(10E10E",
+ "equal(20E20E",
+ "equal(30E30E",
+ "equal(10F10F",
+ "equal(20F20F",
+ "equal(30F30F",
+ "notEqual(10B10B",
+ "notEqual(20B20B",
+ "notEqual(30B30B",
+ "notEqual(10D10D",
+ "notEqual(20D20D",
+ "notEqual(30D30D",
+ "notEqual(10E10E",
+ "notEqual(20E20E",
+ "notEqual(30E30E",
+ "notEqual(10F10F",
+ "notEqual(20F20F",
+ "notEqual(30F30F",
+ "any(10F",
+ "any(20F",
+ "any(30F",
+ "all(10F",
+ "all(20F",
+ "all(30F",
+ "not(10F",
+ "not(20F",
+ "not(30F",
+ "bitfieldExtract(00D00D00D",
+ "bitfieldExtract(10D00D00D",
+ "bitfieldExtract(20D00D00D",
+ "bitfieldExtract(30D00D00D",
+ "bitfieldExtract(00E00D00D",
+ "bitfieldExtract(10E00D00D",
+ "bitfieldExtract(20E00D00D",
+ "bitfieldExtract(30E00D00D",
+ "bitfieldInsert(00D00D00D00D",
+ "bitfieldInsert(10D10D00D00D",
+ "bitfieldInsert(20D20D00D00D",
+ "bitfieldInsert(30D30D00D00D",
+ "bitfieldInsert(00E00E00D00D",
+ "bitfieldInsert(10E10E00D00D",
+ "bitfieldInsert(20E20E00D00D",
+ "bitfieldInsert(30E30E00D00D",
+ "bitfieldReverse(00D",
+ "bitfieldReverse(10D",
+ "bitfieldReverse(20D",
+ "bitfieldReverse(30D",
+ "bitfieldReverse(00E",
+ "bitfieldReverse(10E",
+ "bitfieldReverse(20E",
+ "bitfieldReverse(30E",
+ "bitCount(00D",
+ "bitCount(10D",
+ "bitCount(20D",
+ "bitCount(30D",
+ "bitCount(00E",
+ "bitCount(10E",
+ "bitCount(20E",
+ "bitCount(30E",
+ "findLSB(00D",
+ "findLSB(10D",
+ "findLSB(20D",
+ "findLSB(30D",
+ "findLSB(00E",
+ "findLSB(10E",
+ "findLSB(20E",
+ "findLSB(30E",
+ "findMSB(00D",
+ "findMSB(10D",
+ "findMSB(20D",
+ "findMSB(30D",
+ "findMSB(00E",
+ "findMSB(10E",
+ "findMSB(20E",
+ "findMSB(30E",
+ "uaddCarry(00E00E00E",
+ "uaddCarry(10E10E10E",
+ "uaddCarry(20E20E20E",
+ "uaddCarry(30E30E30E",
+ "usubBorrow(00E00E00E",
+ "usubBorrow(10E10E10E",
+ "usubBorrow(20E20E20E",
+ "usubBorrow(30E30E30E",
+ "umulExtended(00E00E00E00E",
+ "umulExtended(10E10E10E10E",
+ "umulExtended(20E20E20E20E",
+ "umulExtended(30E30E30E30E",
+ "imulExtended(00D00D00D00D",
+ "imulExtended(10D10D10D10D",
+ "imulExtended(20D20D20D20D",
+ "imulExtended(30D30D30D30D",
+ "texture2D(00I10B",
+ "texture2DProj(00I20B",
+ "texture2DProj(00I30B",
+ "textureCube(00K20B",
+ "texture3D(00J20B",
+ "texture3DProj(00J30B",
+ "shadow2DEXT(00d20B",
+ "shadow2DProjEXT(00d30B",
+ "texture2D(00M10B",
+ "texture2DProj(00M20B",
+ "texture2DProj(00M30B",
+ "texture2DRect(00O10B",
+ "texture2DRectProj(00O20B",
+ "texture2DRectProj(00O30B",
+ "texture2DGradEXT(00I10B10B10B",
+ "texture2DProjGradEXT(00I20B10B10B",
+ "texture2DProjGradEXT(00I30B10B10B",
+ "textureCubeGradEXT(00K20B20B20B",
+ "textureVideoWEBGL(00y10B",
+ "texture2D(00I10B00B",
+ "texture2DProj(00I20B00B",
+ "texture2DProj(00I30B00B",
+ "textureCube(00K20B00B",
+ "texture3D(00J20B00B",
+ "texture3DProj(00J30B00B",
+ "texture3DLod(00J20B00B",
+ "texture3DProjLod(00J30B00B",
+ "texture2DLod(00I10B00B",
+ "texture2DProjLod(00I20B00B",
+ "texture2DProjLod(00I30B00B",
+ "textureCubeLod(00K20B00B",
+ "texture2DLodEXT(00I10B00B",
+ "texture2DProjLodEXT(00I20B00B",
+ "texture2DProjLodEXT(00I30B00B",
+ "textureCubeLodEXT(00K20B00B",
+ "texture(00I10B",
+ "texture(00R10B",
+ "texture(00X10B",
+ "texture(00J20B",
+ "texture(00S20B",
+ "texture(00Y20B",
+ "texture(00K20B",
+ "texture(00T20B",
+ "texture(00Z20B",
+ "texture(00L20B",
+ "texture(00U20B",
+ "texture(00a20B",
+ "texture(00d20B",
+ "texture(00e30B",
+ "texture(00f30B",
+ "texture(00k30B",
+ "texture(00s30B",
+ "texture(00x30B",
+ "texture(00l30B00B",
+ "texture(00M10B",
+ "texture(00N10B",
+ "texture(00O10B",
+ "texture(00y10B",
+ "textureProj(00I20B",
+ "textureProj(00R20B",
+ "textureProj(00X20B",
+ "textureProj(00I30B",
+ "textureProj(00R30B",
+ "textureProj(00X30B",
+ "textureProj(00J30B",
+ "textureProj(00S30B",
+ "textureProj(00Y30B",
+ "textureProj(00d30B",
+ "textureProj(00M20B",
+ "textureProj(00M30B",
+ "textureProj(00N20B",
+ "textureProj(00N30B",
+ "textureProj(00O20B",
+ "textureProj(00O30B",
+ "textureLod(00I10B00B",
+ "textureLod(00R10B00B",
+ "textureLod(00X10B00B",
+ "textureLod(00J20B00B",
+ "textureLod(00S20B00B",
+ "textureLod(00Y20B00B",
+ "textureLod(00K20B00B",
+ "textureLod(00T20B00B",
+ "textureLod(00Z20B00B",
+ "textureLod(00L20B00B",
+ "textureLod(00U20B00B",
+ "textureLod(00a20B00B",
+ "textureLod(00d20B00B",
+ "textureLod(00k30B00B",
+ "textureLod(00s30B00B",
+ "textureLod(00x30B00B",
+ "textureSize(00I00D",
+ "textureSize(00R00D",
+ "textureSize(00X00D",
+ "textureSize(00J00D",
+ "textureSize(00S00D",
+ "textureSize(00Y00D",
+ "textureSize(00K00D",
+ "textureSize(00T00D",
+ "textureSize(00Z00D",
+ "textureSize(00L00D",
+ "textureSize(00U00D",
+ "textureSize(00a00D",
+ "textureSize(00d00D",
+ "textureSize(00e00D",
+ "textureSize(00f00D",
+ "textureSize(00k00D",
+ "textureSize(00s00D",
+ "textureSize(00x00D",
+ "textureSize(00l00D",
+ "textureSize(00j",
+ "textureSize(00r",
+ "textureSize(00w",
+ "textureSize(00P",
+ "textureSize(00V",
+ "textureSize(00b",
+ "textureSize(00Q",
+ "textureSize(00W",
+ "textureSize(00c",
+ "textureSize(00M00D",
+ "textureSize(00N00D",
+ "textureProjLod(00I20B00B",
+ "textureProjLod(00R20B00B",
+ "textureProjLod(00X20B00B",
+ "textureProjLod(00I30B00B",
+ "textureProjLod(00R30B00B",
+ "textureProjLod(00X30B00B",
+ "textureProjLod(00J30B00B",
+ "textureProjLod(00S30B00B",
+ "textureProjLod(00Y30B00B",
+ "textureProjLod(00d30B00B",
+ "texelFetch(00I10D00D",
+ "texelFetch(00R10D00D",
+ "texelFetch(00X10D00D",
+ "texelFetch(00J20D00D",
+ "texelFetch(00S20D00D",
+ "texelFetch(00Y20D00D",
+ "texelFetch(00L20D00D",
+ "texelFetch(00U20D00D",
+ "texelFetch(00a20D00D",
+ "texelFetch(00j00D",
+ "texelFetch(00r00D",
+ "texelFetch(00w00D",
+ "texelFetch(00P10D00D",
+ "texelFetch(00V10D00D",
+ "texelFetch(00b10D00D",
+ "texelFetch(00Q20D00D",
+ "texelFetch(00W20D00D",
+ "texelFetch(00c20D00D",
+ "texelFetch(00M10D00D",
+ "texelFetch(00N10D00D",
+ "textureGrad(00I10B10B10B",
+ "textureGrad(00R10B10B10B",
+ "textureGrad(00X10B10B10B",
+ "textureGrad(00J20B20B20B",
+ "textureGrad(00S20B20B20B",
+ "textureGrad(00Y20B20B20B",
+ "textureGrad(00K20B20B20B",
+ "textureGrad(00T20B20B20B",
+ "textureGrad(00Z20B20B20B",
+ "textureGrad(00d20B10B10B",
+ "textureGrad(00e30B20B20B",
+ "textureGrad(00L20B10B10B",
+ "textureGrad(00U20B10B10B",
+ "textureGrad(00a20B10B10B",
+ "textureGrad(00f30B10B10B",
+ "textureGrad(00k30B20B20B",
+ "textureGrad(00s30B20B20B",
+ "textureGrad(00x30B20B20B",
+ "textureProjGrad(00I20B10B10B",
+ "textureProjGrad(00R20B10B10B",
+ "textureProjGrad(00X20B10B10B",
+ "textureProjGrad(00I30B10B10B",
+ "textureProjGrad(00R30B10B10B",
+ "textureProjGrad(00X30B10B10B",
+ "textureProjGrad(00J30B20B20B",
+ "textureProjGrad(00S30B20B20B",
+ "textureProjGrad(00Y30B20B20B",
+ "textureProjGrad(00d30B10B10B",
+ "texture(00I10B00B",
+ "texture(00R10B00B",
+ "texture(00X10B00B",
+ "texture(00J20B00B",
+ "texture(00S20B00B",
+ "texture(00Y20B00B",
+ "texture(00K20B00B",
+ "texture(00T20B00B",
+ "texture(00Z20B00B",
+ "texture(00L20B00B",
+ "texture(00U20B00B",
+ "texture(00a20B00B",
+ "textureProj(00I20B00B",
+ "textureProj(00R20B00B",
+ "textureProj(00X20B00B",
+ "textureProj(00I30B00B",
+ "textureProj(00R30B00B",
+ "textureProj(00X30B00B",
+ "textureProj(00J30B00B",
+ "textureProj(00S30B00B",
+ "textureProj(00Y30B00B",
+ "texture(00d20B00B",
+ "texture(00e30B00B",
+ "textureProj(00d30B00B",
+ "texture(00k30B00B",
+ "texture(00s30B00B",
+ "texture(00x30B00B",
+ "texture(00M10B00B",
+ "textureProj(00M20B00B",
+ "textureProj(00M30B00B",
+ "texture(00N10B00B",
+ "textureProj(00N20B00B",
+ "textureProj(00N30B00B",
+ "textureOffset(00I10B10D",
+ "textureOffset(00R10B10D",
+ "textureOffset(00X10B10D",
+ "textureOffset(00J20B20D",
+ "textureOffset(00S20B20D",
+ "textureOffset(00Y20B20D",
+ "textureOffset(00d20B10D",
+ "textureOffset(00L20B10D",
+ "textureOffset(00U20B10D",
+ "textureOffset(00a20B10D",
+ "textureProjOffset(00I20B10D",
+ "textureProjOffset(00R20B10D",
+ "textureProjOffset(00X20B10D",
+ "textureProjOffset(00I30B10D",
+ "textureProjOffset(00R30B10D",
+ "textureProjOffset(00X30B10D",
+ "textureProjOffset(00J30B20D",
+ "textureProjOffset(00S30B20D",
+ "textureProjOffset(00Y30B20D",
+ "textureProjOffset(00d30B10D",
+ "textureLodOffset(00I10B00B10D",
+ "textureLodOffset(00R10B00B10D",
+ "textureLodOffset(00X10B00B10D",
+ "textureLodOffset(00J20B00B20D",
+ "textureLodOffset(00S20B00B20D",
+ "textureLodOffset(00Y20B00B20D",
+ "textureLodOffset(00d20B00B10D",
+ "textureLodOffset(00L20B00B10D",
+ "textureLodOffset(00U20B00B10D",
+ "textureLodOffset(00a20B00B10D",
+ "textureProjLodOffset(00I20B00B10D",
+ "textureProjLodOffset(00R20B00B10D",
+ "textureProjLodOffset(00X20B00B10D",
+ "textureProjLodOffset(00I30B00B10D",
+ "textureProjLodOffset(00R30B00B10D",
+ "textureProjLodOffset(00X30B00B10D",
+ "textureProjLodOffset(00J30B00B20D",
+ "textureProjLodOffset(00S30B00B20D",
+ "textureProjLodOffset(00Y30B00B20D",
+ "textureProjLodOffset(00d30B00B10D",
+ "texelFetchOffset(00I10D00D10D",
+ "texelFetchOffset(00R10D00D10D",
+ "texelFetchOffset(00X10D00D10D",
+ "texelFetchOffset(00J20D00D20D",
+ "texelFetchOffset(00S20D00D20D",
+ "texelFetchOffset(00Y20D00D20D",
+ "texelFetchOffset(00L20D00D10D",
+ "texelFetchOffset(00U20D00D10D",
+ "texelFetchOffset(00a20D00D10D",
+ "textureGradOffset(00I10B10B10B10D",
+ "textureGradOffset(00R10B10B10B10D",
+ "textureGradOffset(00X10B10B10B10D",
+ "textureGradOffset(00J20B20B20B20D",
+ "textureGradOffset(00S20B20B20B20D",
+ "textureGradOffset(00Y20B20B20B20D",
+ "textureGradOffset(00d20B10B10B10D",
+ "textureGradOffset(00L20B10B10B10D",
+ "textureGradOffset(00U20B10B10B10D",
+ "textureGradOffset(00a20B10B10B10D",
+ "textureGradOffset(00f30B10B10B10D",
+ "textureProjGradOffset(00I20B10B10B10D",
+ "textureProjGradOffset(00R20B10B10B10D",
+ "textureProjGradOffset(00X20B10B10B10D",
+ "textureProjGradOffset(00I30B10B10B10D",
+ "textureProjGradOffset(00R30B10B10B10D",
+ "textureProjGradOffset(00X30B10B10B10D",
+ "textureProjGradOffset(00J30B20B20B20D",
+ "textureProjGradOffset(00S30B20B20B20D",
+ "textureProjGradOffset(00Y30B20B20B20D",
+ "textureProjGradOffset(00d30B10B10B10D",
+ "textureOffset(00I10B10D00B",
+ "textureOffset(00R10B10D00B",
+ "textureOffset(00X10B10D00B",
+ "textureOffset(00J20B20D00B",
+ "textureOffset(00S20B20D00B",
+ "textureOffset(00Y20B20D00B",
+ "textureOffset(00d20B10D00B",
+ "textureOffset(00L20B10D00B",
+ "textureOffset(00U20B10D00B",
+ "textureOffset(00a20B10D00B",
+ "textureProjOffset(00I20B10D00B",
+ "textureProjOffset(00R20B10D00B",
+ "textureProjOffset(00X20B10D00B",
+ "textureProjOffset(00I30B10D00B",
+ "textureProjOffset(00R30B10D00B",
+ "textureProjOffset(00X30B10D00B",
+ "textureProjOffset(00J30B20D00B",
+ "textureProjOffset(00S30B20D00B",
+ "textureProjOffset(00Y30B20D00B",
+ "textureProjOffset(00d30B10D00B",
+ "textureGather(00I10B",
+ "textureGather(00R10B",
+ "textureGather(00X10B",
+ "textureGather(00I10B00D",
+ "textureGather(00R10B00D",
+ "textureGather(00X10B00D",
+ "textureGather(00L20B",
+ "textureGather(00U20B",
+ "textureGather(00a20B",
+ "textureGather(00L20B00D",
+ "textureGather(00U20B00D",
+ "textureGather(00a20B00D",
+ "textureGather(00K20B",
+ "textureGather(00T20B",
+ "textureGather(00Z20B",
+ "textureGather(00K20B00D",
+ "textureGather(00T20B00D",
+ "textureGather(00Z20B00D",
+ "textureGather(00k30B",
+ "textureGather(00s30B",
+ "textureGather(00x30B",
+ "textureGather(00k30B00D",
+ "textureGather(00s30B00D",
+ "textureGather(00x30B00D",
+ "textureGather(00l30B00B",
+ "textureGather(00d10B",
+ "textureGather(00d10B00B",
+ "textureGather(00f20B",
+ "textureGather(00f20B00B",
+ "textureGather(00e20B",
+ "textureGather(00e20B00B",
+ "textureGatherOffset(00I10B10D",
+ "textureGatherOffset(00R10B10D",
+ "textureGatherOffset(00X10B10D",
+ "textureGatherOffset(00L20B10D",
+ "textureGatherOffset(00U20B10D",
+ "textureGatherOffset(00a20B10D",
+ "textureGatherOffset(00d10B00B10D",
+ "textureGatherOffset(00f20B00B10D",
+ "textureGatherOffset(00I10B10D00D",
+ "textureGatherOffset(00R10B10D00D",
+ "textureGatherOffset(00X10B10D00D",
+ "textureGatherOffset(00L20B10D00D",
+ "textureGatherOffset(00U20B10D00D",
+ "textureGatherOffset(00a20B10D00D",
+ "textureGatherOffsets(00I10B10Dx4",
+ "textureGatherOffsets(00R10B10Dx4",
+ "textureGatherOffsets(00X10B10Dx4",
+ "textureGatherOffsets(00L20B10Dx4",
+ "textureGatherOffsets(00U20B10Dx4",
+ "textureGatherOffsets(00a20B10Dx4",
+ "textureGatherOffsets(00d10B00B10Dx4",
+ "textureGatherOffsets(00f20B00B10Dx4",
+ "textureGatherOffsets(00I10B10Dx400D",
+ "textureGatherOffsets(00R10B10Dx400D",
+ "textureGatherOffsets(00X10B10Dx400D",
+ "textureGatherOffsets(00L20B10Dx400D",
+ "textureGatherOffsets(00U20B10Dx400D",
+ "textureGatherOffsets(00a20B10Dx400D",
+ "rgb_2_yuv(20B00H",
+ "yuv_2_rgb(20B00H",
+ "dFdx(00B",
+ "dFdx(10B",
+ "dFdx(20B",
+ "dFdx(30B",
+ "dFdy(00B",
+ "dFdy(10B",
+ "dFdy(20B",
+ "dFdy(30B",
+ "fwidth(00B",
+ "fwidth(10B",
+ "fwidth(20B",
+ "fwidth(30B",
+ "interpolateAtCentroid(00B",
+ "interpolateAtCentroid(10B",
+ "interpolateAtCentroid(20B",
+ "interpolateAtCentroid(30B",
+ "interpolateAtSample(00B00D",
+ "interpolateAtSample(10B00D",
+ "interpolateAtSample(20B00D",
+ "interpolateAtSample(30B00D",
+ "interpolateAtOffset(00B10B",
+ "interpolateAtOffset(10B10B",
+ "interpolateAtOffset(20B10B",
+ "interpolateAtOffset(30B10B",
+ "atomicCounter(00G",
+ "atomicCounterIncrement(00G",
+ "atomicCounterDecrement(00G",
+ "atomicAdd(00E00E",
+ "atomicAdd(00D00D",
+ "atomicMin(00E00E",
+ "atomicMin(00D00D",
+ "atomicMax(00E00E",
+ "atomicMax(00D00D",
+ "atomicAnd(00E00E",
+ "atomicAnd(00D00D",
+ "atomicOr(00E00E",
+ "atomicOr(00D00D",
+ "atomicXor(00E00E",
+ "atomicXor(00D00D",
+ "atomicExchange(00E00E",
+ "atomicExchange(00D00D",
+ "atomicCompSwap(00E00E00E",
+ "atomicCompSwap(00D00D00D",
+ "imageSize(00z",
+ "imageSize(01K",
+ "imageSize(01V",
+ "imageSize(01A",
+ "imageSize(01L",
+ "imageSize(01W",
+ "imageSize(01B",
+ "imageSize(01M",
+ "imageSize(01X",
+ "imageSize(01C",
+ "imageSize(01N",
+ "imageSize(01Y",
+ "imageSize(01H",
+ "imageSize(01S",
+ "imageSize(01d",
+ "imageSize(01J",
+ "imageSize(01U",
+ "imageSize(01f",
+ "imageStore(00z10D30B",
+ "imageStore(01K10D30D",
+ "imageStore(01V10D30E",
+ "imageStore(01A20D30B",
+ "imageStore(01L20D30D",
+ "imageStore(01W20D30E",
+ "imageStore(01B20D30B",
+ "imageStore(01M20D30D",
+ "imageStore(01X20D30E",
+ "imageStore(01C20D30B",
+ "imageStore(01N20D30D",
+ "imageStore(01Y20D30E",
+ "imageStore(01H20D30B",
+ "imageStore(01S20D30D",
+ "imageStore(01d20D30E",
+ "imageStore(01J00D30B",
+ "imageStore(01U00D30D",
+ "imageStore(01f00D30E",
+ "imageLoad(00z10D",
+ "imageLoad(01K10D",
+ "imageLoad(01V10D",
+ "imageLoad(01A20D",
+ "imageLoad(01L20D",
+ "imageLoad(01W20D",
+ "imageLoad(01B20D",
+ "imageLoad(01M20D",
+ "imageLoad(01X20D",
+ "imageLoad(01C20D",
+ "imageLoad(01N20D",
+ "imageLoad(01Y20D",
+ "imageLoad(01H20D",
+ "imageLoad(01S20D",
+ "imageLoad(01d20D",
+ "imageLoad(01J00D",
+ "imageLoad(01U00D",
+ "imageLoad(01f00D",
+ "imageAtomicAdd(00z10D00E",
+ "imageAtomicAdd(01K10D00E",
+ "imageAtomicAdd(01V10D00E",
+ "imageAtomicAdd(01A20D00E",
+ "imageAtomicAdd(01L20D00E",
+ "imageAtomicAdd(01W20D00E",
+ "imageAtomicAdd(01C20D00E",
+ "imageAtomicAdd(01N20D00E",
+ "imageAtomicAdd(01Y20D00E",
+ "imageAtomicAdd(01J00D00E",
+ "imageAtomicAdd(01U00D00E",
+ "imageAtomicAdd(01f00D00E",
+ "imageAtomicAdd(01B20D00E",
+ "imageAtomicAdd(01M20D00E",
+ "imageAtomicAdd(01X20D00E",
+ "imageAtomicAdd(01H20D00E",
+ "imageAtomicAdd(01S20D00E",
+ "imageAtomicAdd(01d20D00E",
+ "imageAtomicAdd(01D00D00E",
+ "imageAtomicAdd(01O00D00E",
+ "imageAtomicAdd(01Z00D00E",
+ "imageAtomicAdd(01E10D00E",
+ "imageAtomicAdd(01P10D00E",
+ "imageAtomicAdd(01a10D00E",
+ "imageAtomicAdd(01I10D00E",
+ "imageAtomicAdd(01T10D00E",
+ "imageAtomicAdd(01e10D00E",
+ "imageAtomicAdd(01F10D00D00E",
+ "imageAtomicAdd(01Q10D00D00E",
+ "imageAtomicAdd(01b10D00D00E",
+ "imageAtomicAdd(01G20D00D00E",
+ "imageAtomicAdd(01R20D00D00E",
+ "imageAtomicAdd(01c20D00D00E",
+ "imageAtomicAdd(00z10D00D",
+ "imageAtomicAdd(01K10D00D",
+ "imageAtomicAdd(01V10D00D",
+ "imageAtomicAdd(01A20D00D",
+ "imageAtomicAdd(01L20D00D",
+ "imageAtomicAdd(01W20D00D",
+ "imageAtomicAdd(01C20D00D",
+ "imageAtomicAdd(01N20D00D",
+ "imageAtomicAdd(01Y20D00D",
+ "imageAtomicAdd(01J00D00D",
+ "imageAtomicAdd(01U00D00D",
+ "imageAtomicAdd(01f00D00D",
+ "imageAtomicAdd(01B20D00D",
+ "imageAtomicAdd(01M20D00D",
+ "imageAtomicAdd(01X20D00D",
+ "imageAtomicAdd(01H20D00D",
+ "imageAtomicAdd(01S20D00D",
+ "imageAtomicAdd(01d20D00D",
+ "imageAtomicAdd(01D00D00D",
+ "imageAtomicAdd(01O00D00D",
+ "imageAtomicAdd(01Z00D00D",
+ "imageAtomicAdd(01E10D00D",
+ "imageAtomicAdd(01P10D00D",
+ "imageAtomicAdd(01a10D00D",
+ "imageAtomicAdd(01I10D00D",
+ "imageAtomicAdd(01T10D00D",
+ "imageAtomicAdd(01e10D00D",
+ "imageAtomicAdd(01F10D00D00D",
+ "imageAtomicAdd(01Q10D00D00D",
+ "imageAtomicAdd(01b10D00D00D",
+ "imageAtomicAdd(01G20D00D00D",
+ "imageAtomicAdd(01R20D00D00D",
+ "imageAtomicAdd(01c20D00D00D",
+ "imageAtomicMin(00z10D00E",
+ "imageAtomicMin(01K10D00E",
+ "imageAtomicMin(01V10D00E",
+ "imageAtomicMin(01A20D00E",
+ "imageAtomicMin(01L20D00E",
+ "imageAtomicMin(01W20D00E",
+ "imageAtomicMin(01C20D00E",
+ "imageAtomicMin(01N20D00E",
+ "imageAtomicMin(01Y20D00E",
+ "imageAtomicMin(01J00D00E",
+ "imageAtomicMin(01U00D00E",
+ "imageAtomicMin(01f00D00E",
+ "imageAtomicMin(01B20D00E",
+ "imageAtomicMin(01M20D00E",
+ "imageAtomicMin(01X20D00E",
+ "imageAtomicMin(01H20D00E",
+ "imageAtomicMin(01S20D00E",
+ "imageAtomicMin(01d20D00E",
+ "imageAtomicMin(01D00D00E",
+ "imageAtomicMin(01O00D00E",
+ "imageAtomicMin(01Z00D00E",
+ "imageAtomicMin(01E10D00E",
+ "imageAtomicMin(01P10D00E",
+ "imageAtomicMin(01a10D00E",
+ "imageAtomicMin(01I10D00E",
+ "imageAtomicMin(01T10D00E",
+ "imageAtomicMin(01e10D00E",
+ "imageAtomicMin(01F10D00D00E",
+ "imageAtomicMin(01Q10D00D00E",
+ "imageAtomicMin(01b10D00D00E",
+ "imageAtomicMin(01G20D00D00E",
+ "imageAtomicMin(01R20D00D00E",
+ "imageAtomicMin(01c20D00D00E",
+ "imageAtomicMin(00z10D00D",
+ "imageAtomicMin(01K10D00D",
+ "imageAtomicMin(01V10D00D",
+ "imageAtomicMin(01A20D00D",
+ "imageAtomicMin(01L20D00D",
+ "imageAtomicMin(01W20D00D",
+ "imageAtomicMin(01C20D00D",
+ "imageAtomicMin(01N20D00D",
+ "imageAtomicMin(01Y20D00D",
+ "imageAtomicMin(01J00D00D",
+ "imageAtomicMin(01U00D00D",
+ "imageAtomicMin(01f00D00D",
+ "imageAtomicMin(01B20D00D",
+ "imageAtomicMin(01M20D00D",
+ "imageAtomicMin(01X20D00D",
+ "imageAtomicMin(01H20D00D",
+ "imageAtomicMin(01S20D00D",
+ "imageAtomicMin(01d20D00D",
+ "imageAtomicMin(01D00D00D",
+ "imageAtomicMin(01O00D00D",
+ "imageAtomicMin(01Z00D00D",
+ "imageAtomicMin(01E10D00D",
+ "imageAtomicMin(01P10D00D",
+ "imageAtomicMin(01a10D00D",
+ "imageAtomicMin(01I10D00D",
+ "imageAtomicMin(01T10D00D",
+ "imageAtomicMin(01e10D00D",
+ "imageAtomicMin(01F10D00D00D",
+ "imageAtomicMin(01Q10D00D00D",
+ "imageAtomicMin(01b10D00D00D",
+ "imageAtomicMin(01G20D00D00D",
+ "imageAtomicMin(01R20D00D00D",
+ "imageAtomicMin(01c20D00D00D",
+ "imageAtomicMax(00z10D00E",
+ "imageAtomicMax(01K10D00E",
+ "imageAtomicMax(01V10D00E",
+ "imageAtomicMax(01A20D00E",
+ "imageAtomicMax(01L20D00E",
+ "imageAtomicMax(01W20D00E",
+ "imageAtomicMax(01C20D00E",
+ "imageAtomicMax(01N20D00E",
+ "imageAtomicMax(01Y20D00E",
+ "imageAtomicMax(01J00D00E",
+ "imageAtomicMax(01U00D00E",
+ "imageAtomicMax(01f00D00E",
+ "imageAtomicMax(01B20D00E",
+ "imageAtomicMax(01M20D00E",
+ "imageAtomicMax(01X20D00E",
+ "imageAtomicMax(01H20D00E",
+ "imageAtomicMax(01S20D00E",
+ "imageAtomicMax(01d20D00E",
+ "imageAtomicMax(01D00D00E",
+ "imageAtomicMax(01O00D00E",
+ "imageAtomicMax(01Z00D00E",
+ "imageAtomicMax(01E10D00E",
+ "imageAtomicMax(01P10D00E",
+ "imageAtomicMax(01a10D00E",
+ "imageAtomicMax(01I10D00E",
+ "imageAtomicMax(01T10D00E",
+ "imageAtomicMax(01e10D00E",
+ "imageAtomicMax(01F10D00D00E",
+ "imageAtomicMax(01Q10D00D00E",
+ "imageAtomicMax(01b10D00D00E",
+ "imageAtomicMax(01G20D00D00E",
+ "imageAtomicMax(01R20D00D00E",
+ "imageAtomicMax(01c20D00D00E",
+ "imageAtomicMax(00z10D00D",
+ "imageAtomicMax(01K10D00D",
+ "imageAtomicMax(01V10D00D",
+ "imageAtomicMax(01A20D00D",
+ "imageAtomicMax(01L20D00D",
+ "imageAtomicMax(01W20D00D",
+ "imageAtomicMax(01C20D00D",
+ "imageAtomicMax(01N20D00D",
+ "imageAtomicMax(01Y20D00D",
+ "imageAtomicMax(01J00D00D",
+ "imageAtomicMax(01U00D00D",
+ "imageAtomicMax(01f00D00D",
+ "imageAtomicMax(01B20D00D",
+ "imageAtomicMax(01M20D00D",
+ "imageAtomicMax(01X20D00D",
+ "imageAtomicMax(01H20D00D",
+ "imageAtomicMax(01S20D00D",
+ "imageAtomicMax(01d20D00D",
+ "imageAtomicMax(01D00D00D",
+ "imageAtomicMax(01O00D00D",
+ "imageAtomicMax(01Z00D00D",
+ "imageAtomicMax(01E10D00D",
+ "imageAtomicMax(01P10D00D",
+ "imageAtomicMax(01a10D00D",
+ "imageAtomicMax(01I10D00D",
+ "imageAtomicMax(01T10D00D",
+ "imageAtomicMax(01e10D00D",
+ "imageAtomicMax(01F10D00D00D",
+ "imageAtomicMax(01Q10D00D00D",
+ "imageAtomicMax(01b10D00D00D",
+ "imageAtomicMax(01G20D00D00D",
+ "imageAtomicMax(01R20D00D00D",
+ "imageAtomicMax(01c20D00D00D",
+ "imageAtomicAnd(00z10D00E",
+ "imageAtomicAnd(01K10D00E",
+ "imageAtomicAnd(01V10D00E",
+ "imageAtomicAnd(01A20D00E",
+ "imageAtomicAnd(01L20D00E",
+ "imageAtomicAnd(01W20D00E",
+ "imageAtomicAnd(01C20D00E",
+ "imageAtomicAnd(01N20D00E",
+ "imageAtomicAnd(01Y20D00E",
+ "imageAtomicAnd(01J00D00E",
+ "imageAtomicAnd(01U00D00E",
+ "imageAtomicAnd(01f00D00E",
+ "imageAtomicAnd(01B20D00E",
+ "imageAtomicAnd(01M20D00E",
+ "imageAtomicAnd(01X20D00E",
+ "imageAtomicAnd(01H20D00E",
+ "imageAtomicAnd(01S20D00E",
+ "imageAtomicAnd(01d20D00E",
+ "imageAtomicAnd(01D00D00E",
+ "imageAtomicAnd(01O00D00E",
+ "imageAtomicAnd(01Z00D00E",
+ "imageAtomicAnd(01E10D00E",
+ "imageAtomicAnd(01P10D00E",
+ "imageAtomicAnd(01a10D00E",
+ "imageAtomicAnd(01I10D00E",
+ "imageAtomicAnd(01T10D00E",
+ "imageAtomicAnd(01e10D00E",
+ "imageAtomicAnd(01F10D00D00E",
+ "imageAtomicAnd(01Q10D00D00E",
+ "imageAtomicAnd(01b10D00D00E",
+ "imageAtomicAnd(01G20D00D00E",
+ "imageAtomicAnd(01R20D00D00E",
+ "imageAtomicAnd(01c20D00D00E",
+ "imageAtomicAnd(00z10D00D",
+ "imageAtomicAnd(01K10D00D",
+ "imageAtomicAnd(01V10D00D",
+ "imageAtomicAnd(01A20D00D",
+ "imageAtomicAnd(01L20D00D",
+ "imageAtomicAnd(01W20D00D",
+ "imageAtomicAnd(01C20D00D",
+ "imageAtomicAnd(01N20D00D",
+ "imageAtomicAnd(01Y20D00D",
+ "imageAtomicAnd(01J00D00D",
+ "imageAtomicAnd(01U00D00D",
+ "imageAtomicAnd(01f00D00D",
+ "imageAtomicAnd(01B20D00D",
+ "imageAtomicAnd(01M20D00D",
+ "imageAtomicAnd(01X20D00D",
+ "imageAtomicAnd(01H20D00D",
+ "imageAtomicAnd(01S20D00D",
+ "imageAtomicAnd(01d20D00D",
+ "imageAtomicAnd(01D00D00D",
+ "imageAtomicAnd(01O00D00D",
+ "imageAtomicAnd(01Z00D00D",
+ "imageAtomicAnd(01E10D00D",
+ "imageAtomicAnd(01P10D00D",
+ "imageAtomicAnd(01a10D00D",
+ "imageAtomicAnd(01I10D00D",
+ "imageAtomicAnd(01T10D00D",
+ "imageAtomicAnd(01e10D00D",
+ "imageAtomicAnd(01F10D00D00D",
+ "imageAtomicAnd(01Q10D00D00D",
+ "imageAtomicAnd(01b10D00D00D",
+ "imageAtomicAnd(01G20D00D00D",
+ "imageAtomicAnd(01R20D00D00D",
+ "imageAtomicAnd(01c20D00D00D",
+ "imageAtomicOr(00z10D00E",
+ "imageAtomicOr(01K10D00E",
+ "imageAtomicOr(01V10D00E",
+ "imageAtomicOr(01A20D00E",
+ "imageAtomicOr(01L20D00E",
+ "imageAtomicOr(01W20D00E",
+ "imageAtomicOr(01C20D00E",
+ "imageAtomicOr(01N20D00E",
+ "imageAtomicOr(01Y20D00E",
+ "imageAtomicOr(01J00D00E",
+ "imageAtomicOr(01U00D00E",
+ "imageAtomicOr(01f00D00E",
+ "imageAtomicOr(01B20D00E",
+ "imageAtomicOr(01M20D00E",
+ "imageAtomicOr(01X20D00E",
+ "imageAtomicOr(01H20D00E",
+ "imageAtomicOr(01S20D00E",
+ "imageAtomicOr(01d20D00E",
+ "imageAtomicOr(01D00D00E",
+ "imageAtomicOr(01O00D00E",
+ "imageAtomicOr(01Z00D00E",
+ "imageAtomicOr(01E10D00E",
+ "imageAtomicOr(01P10D00E",
+ "imageAtomicOr(01a10D00E",
+ "imageAtomicOr(01I10D00E",
+ "imageAtomicOr(01T10D00E",
+ "imageAtomicOr(01e10D00E",
+ "imageAtomicOr(01F10D00D00E",
+ "imageAtomicOr(01Q10D00D00E",
+ "imageAtomicOr(01b10D00D00E",
+ "imageAtomicOr(01G20D00D00E",
+ "imageAtomicOr(01R20D00D00E",
+ "imageAtomicOr(01c20D00D00E",
+ "imageAtomicOr(00z10D00D",
+ "imageAtomicOr(01K10D00D",
+ "imageAtomicOr(01V10D00D",
+ "imageAtomicOr(01A20D00D",
+ "imageAtomicOr(01L20D00D",
+ "imageAtomicOr(01W20D00D",
+ "imageAtomicOr(01C20D00D",
+ "imageAtomicOr(01N20D00D",
+ "imageAtomicOr(01Y20D00D",
+ "imageAtomicOr(01J00D00D",
+ "imageAtomicOr(01U00D00D",
+ "imageAtomicOr(01f00D00D",
+ "imageAtomicOr(01B20D00D",
+ "imageAtomicOr(01M20D00D",
+ "imageAtomicOr(01X20D00D",
+ "imageAtomicOr(01H20D00D",
+ "imageAtomicOr(01S20D00D",
+ "imageAtomicOr(01d20D00D",
+ "imageAtomicOr(01D00D00D",
+ "imageAtomicOr(01O00D00D",
+ "imageAtomicOr(01Z00D00D",
+ "imageAtomicOr(01E10D00D",
+ "imageAtomicOr(01P10D00D",
+ "imageAtomicOr(01a10D00D",
+ "imageAtomicOr(01I10D00D",
+ "imageAtomicOr(01T10D00D",
+ "imageAtomicOr(01e10D00D",
+ "imageAtomicOr(01F10D00D00D",
+ "imageAtomicOr(01Q10D00D00D",
+ "imageAtomicOr(01b10D00D00D",
+ "imageAtomicOr(01G20D00D00D",
+ "imageAtomicOr(01R20D00D00D",
+ "imageAtomicOr(01c20D00D00D",
+ "imageAtomicXor(00z10D00E",
+ "imageAtomicXor(01K10D00E",
+ "imageAtomicXor(01V10D00E",
+ "imageAtomicXor(01A20D00E",
+ "imageAtomicXor(01L20D00E",
+ "imageAtomicXor(01W20D00E",
+ "imageAtomicXor(01C20D00E",
+ "imageAtomicXor(01N20D00E",
+ "imageAtomicXor(01Y20D00E",
+ "imageAtomicXor(01J00D00E",
+ "imageAtomicXor(01U00D00E",
+ "imageAtomicXor(01f00D00E",
+ "imageAtomicXor(01B20D00E",
+ "imageAtomicXor(01M20D00E",
+ "imageAtomicXor(01X20D00E",
+ "imageAtomicXor(01H20D00E",
+ "imageAtomicXor(01S20D00E",
+ "imageAtomicXor(01d20D00E",
+ "imageAtomicXor(01D00D00E",
+ "imageAtomicXor(01O00D00E",
+ "imageAtomicXor(01Z00D00E",
+ "imageAtomicXor(01E10D00E",
+ "imageAtomicXor(01P10D00E",
+ "imageAtomicXor(01a10D00E",
+ "imageAtomicXor(01I10D00E",
+ "imageAtomicXor(01T10D00E",
+ "imageAtomicXor(01e10D00E",
+ "imageAtomicXor(01F10D00D00E",
+ "imageAtomicXor(01Q10D00D00E",
+ "imageAtomicXor(01b10D00D00E",
+ "imageAtomicXor(01G20D00D00E",
+ "imageAtomicXor(01R20D00D00E",
+ "imageAtomicXor(01c20D00D00E",
+ "imageAtomicXor(00z10D00D",
+ "imageAtomicXor(01K10D00D",
+ "imageAtomicXor(01V10D00D",
+ "imageAtomicXor(01A20D00D",
+ "imageAtomicXor(01L20D00D",
+ "imageAtomicXor(01W20D00D",
+ "imageAtomicXor(01C20D00D",
+ "imageAtomicXor(01N20D00D",
+ "imageAtomicXor(01Y20D00D",
+ "imageAtomicXor(01J00D00D",
+ "imageAtomicXor(01U00D00D",
+ "imageAtomicXor(01f00D00D",
+ "imageAtomicXor(01B20D00D",
+ "imageAtomicXor(01M20D00D",
+ "imageAtomicXor(01X20D00D",
+ "imageAtomicXor(01H20D00D",
+ "imageAtomicXor(01S20D00D",
+ "imageAtomicXor(01d20D00D",
+ "imageAtomicXor(01D00D00D",
+ "imageAtomicXor(01O00D00D",
+ "imageAtomicXor(01Z00D00D",
+ "imageAtomicXor(01E10D00D",
+ "imageAtomicXor(01P10D00D",
+ "imageAtomicXor(01a10D00D",
+ "imageAtomicXor(01I10D00D",
+ "imageAtomicXor(01T10D00D",
+ "imageAtomicXor(01e10D00D",
+ "imageAtomicXor(01F10D00D00D",
+ "imageAtomicXor(01Q10D00D00D",
+ "imageAtomicXor(01b10D00D00D",
+ "imageAtomicXor(01G20D00D00D",
+ "imageAtomicXor(01R20D00D00D",
+ "imageAtomicXor(01c20D00D00D",
+ "imageAtomicExchange(00z10D00E",
+ "imageAtomicExchange(01K10D00E",
+ "imageAtomicExchange(01V10D00E",
+ "imageAtomicExchange(01A20D00E",
+ "imageAtomicExchange(01L20D00E",
+ "imageAtomicExchange(01W20D00E",
+ "imageAtomicExchange(01C20D00E",
+ "imageAtomicExchange(01N20D00E",
+ "imageAtomicExchange(01Y20D00E",
+ "imageAtomicExchange(01J00D00E",
+ "imageAtomicExchange(01U00D00E",
+ "imageAtomicExchange(01f00D00E",
+ "imageAtomicExchange(01B20D00E",
+ "imageAtomicExchange(01M20D00E",
+ "imageAtomicExchange(01X20D00E",
+ "imageAtomicExchange(01H20D00E",
+ "imageAtomicExchange(01S20D00E",
+ "imageAtomicExchange(01d20D00E",
+ "imageAtomicExchange(01D00D00E",
+ "imageAtomicExchange(01O00D00E",
+ "imageAtomicExchange(01Z00D00E",
+ "imageAtomicExchange(01E10D00E",
+ "imageAtomicExchange(01P10D00E",
+ "imageAtomicExchange(01a10D00E",
+ "imageAtomicExchange(01I10D00E",
+ "imageAtomicExchange(01T10D00E",
+ "imageAtomicExchange(01e10D00E",
+ "imageAtomicExchange(01F10D00D00E",
+ "imageAtomicExchange(01Q10D00D00E",
+ "imageAtomicExchange(01b10D00D00E",
+ "imageAtomicExchange(01G20D00D00E",
+ "imageAtomicExchange(01R20D00D00E",
+ "imageAtomicExchange(01c20D00D00E",
+ "imageAtomicExchange(00z10D00D",
+ "imageAtomicExchange(01K10D00D",
+ "imageAtomicExchange(01V10D00D",
+ "imageAtomicExchange(01A20D00D",
+ "imageAtomicExchange(01L20D00D",
+ "imageAtomicExchange(01W20D00D",
+ "imageAtomicExchange(01C20D00D",
+ "imageAtomicExchange(01N20D00D",
+ "imageAtomicExchange(01Y20D00D",
+ "imageAtomicExchange(01J00D00D",
+ "imageAtomicExchange(01U00D00D",
+ "imageAtomicExchange(01f00D00D",
+ "imageAtomicExchange(01B20D00D",
+ "imageAtomicExchange(01M20D00D",
+ "imageAtomicExchange(01X20D00D",
+ "imageAtomicExchange(01H20D00D",
+ "imageAtomicExchange(01S20D00D",
+ "imageAtomicExchange(01d20D00D",
+ "imageAtomicExchange(01D00D00D",
+ "imageAtomicExchange(01O00D00D",
+ "imageAtomicExchange(01Z00D00D",
+ "imageAtomicExchange(01E10D00D",
+ "imageAtomicExchange(01P10D00D",
+ "imageAtomicExchange(01a10D00D",
+ "imageAtomicExchange(01I10D00D",
+ "imageAtomicExchange(01T10D00D",
+ "imageAtomicExchange(01e10D00D",
+ "imageAtomicExchange(01F10D00D00D",
+ "imageAtomicExchange(01Q10D00D00D",
+ "imageAtomicExchange(01b10D00D00D",
+ "imageAtomicExchange(01G20D00D00D",
+ "imageAtomicExchange(01R20D00D00D",
+ "imageAtomicExchange(01c20D00D00D",
+ "imageAtomicExchange(00z10D00B",
+ "imageAtomicExchange(01K10D00B",
+ "imageAtomicExchange(01V10D00B",
+ "imageAtomicExchange(01A20D00B",
+ "imageAtomicExchange(01L20D00B",
+ "imageAtomicExchange(01W20D00B",
+ "imageAtomicExchange(01C20D00B",
+ "imageAtomicExchange(01N20D00B",
+ "imageAtomicExchange(01Y20D00B",
+ "imageAtomicExchange(01J00D00B",
+ "imageAtomicExchange(01U00D00B",
+ "imageAtomicExchange(01f00D00B",
+ "imageAtomicExchange(01B20D00B",
+ "imageAtomicExchange(01M20D00B",
+ "imageAtomicExchange(01X20D00B",
+ "imageAtomicExchange(01H20D00B",
+ "imageAtomicExchange(01S20D00B",
+ "imageAtomicExchange(01d20D00B",
+ "imageAtomicExchange(01D00D00B",
+ "imageAtomicExchange(01O00D00B",
+ "imageAtomicExchange(01Z00D00B",
+ "imageAtomicExchange(01E10D00B",
+ "imageAtomicExchange(01P10D00B",
+ "imageAtomicExchange(01a10D00B",
+ "imageAtomicExchange(01I10D00B",
+ "imageAtomicExchange(01T10D00B",
+ "imageAtomicExchange(01e10D00B",
+ "imageAtomicExchange(01F10D00D00B",
+ "imageAtomicExchange(01Q10D00D00B",
+ "imageAtomicExchange(01b10D00D00B",
+ "imageAtomicExchange(01G20D00D00B",
+ "imageAtomicExchange(01R20D00D00B",
+ "imageAtomicExchange(01c20D00D00B",
+ "imageAtomicCompSwap(00z10D00E00E",
+ "imageAtomicCompSwap(01K10D00E00E",
+ "imageAtomicCompSwap(01V10D00E00E",
+ "imageAtomicCompSwap(01A20D00E00E",
+ "imageAtomicCompSwap(01L20D00E00E",
+ "imageAtomicCompSwap(01W20D00E00E",
+ "imageAtomicCompSwap(01C20D00E00E",
+ "imageAtomicCompSwap(01N20D00E00E",
+ "imageAtomicCompSwap(01Y20D00E00E",
+ "imageAtomicCompSwap(01J00D00E00E",
+ "imageAtomicCompSwap(01U00D00E00E",
+ "imageAtomicCompSwap(01f00D00E00E",
+ "imageAtomicCompSwap(01B20D00E00E",
+ "imageAtomicCompSwap(01M20D00E00E",
+ "imageAtomicCompSwap(01X20D00E00E",
+ "imageAtomicCompSwap(01H20D00E00E",
+ "imageAtomicCompSwap(01S20D00E00E",
+ "imageAtomicCompSwap(01d20D00E00E",
+ "imageAtomicCompSwap(01D00D00E00E",
+ "imageAtomicCompSwap(01O00D00E00E",
+ "imageAtomicCompSwap(01Z00D00E00E",
+ "imageAtomicCompSwap(01E10D00E00E",
+ "imageAtomicCompSwap(01P10D00E00E",
+ "imageAtomicCompSwap(01a10D00E00E",
+ "imageAtomicCompSwap(01I10D00E00E",
+ "imageAtomicCompSwap(01T10D00E00E",
+ "imageAtomicCompSwap(01e10D00E00E",
+ "imageAtomicCompSwap(01F10D00D00E00E",
+ "imageAtomicCompSwap(01Q10D00D00E00E",
+ "imageAtomicCompSwap(01b10D00D00E00E",
+ "imageAtomicCompSwap(01G20D00D00E00E",
+ "imageAtomicCompSwap(01R20D00D00E00E",
+ "imageAtomicCompSwap(01c20D00D00E00E",
+ "imageAtomicCompSwap(00z10D00D00D",
+ "imageAtomicCompSwap(01K10D00D00D",
+ "imageAtomicCompSwap(01V10D00D00D",
+ "imageAtomicCompSwap(01A20D00D00D",
+ "imageAtomicCompSwap(01L20D00D00D",
+ "imageAtomicCompSwap(01W20D00D00D",
+ "imageAtomicCompSwap(01C20D00D00D",
+ "imageAtomicCompSwap(01N20D00D00D",
+ "imageAtomicCompSwap(01Y20D00D00D",
+ "imageAtomicCompSwap(01J00D00D00D",
+ "imageAtomicCompSwap(01U00D00D00D",
+ "imageAtomicCompSwap(01f00D00D00D",
+ "imageAtomicCompSwap(01B20D00D00D",
+ "imageAtomicCompSwap(01M20D00D00D",
+ "imageAtomicCompSwap(01X20D00D00D",
+ "imageAtomicCompSwap(01H20D00D00D",
+ "imageAtomicCompSwap(01S20D00D00D",
+ "imageAtomicCompSwap(01d20D00D00D",
+ "imageAtomicCompSwap(01D00D00D00D",
+ "imageAtomicCompSwap(01O00D00D00D",
+ "imageAtomicCompSwap(01Z00D00D00D",
+ "imageAtomicCompSwap(01E10D00D00D",
+ "imageAtomicCompSwap(01P10D00D00D",
+ "imageAtomicCompSwap(01a10D00D00D",
+ "imageAtomicCompSwap(01I10D00D00D",
+ "imageAtomicCompSwap(01T10D00D00D",
+ "imageAtomicCompSwap(01e10D00D00D",
+ "imageAtomicCompSwap(01F10D00D00D00D",
+ "imageAtomicCompSwap(01Q10D00D00D00D",
+ "imageAtomicCompSwap(01b10D00D00D00D",
+ "imageAtomicCompSwap(01G20D00D00D00D",
+ "imageAtomicCompSwap(01R20D00D00D00D",
+ "imageAtomicCompSwap(01c20D00D00D00D",
+ "pixelLocalLoadANGLE(01g",
+ "pixelLocalLoadANGLE(01h",
+ "pixelLocalLoadANGLE(01i",
+ "pixelLocalStoreANGLE(01g30B",
+ "pixelLocalStoreANGLE(01h30D",
+ "pixelLocalStoreANGLE(01i30E",
+ "beginInvocationInterlockNV(",
+ "endInvocationInterlockNV(",
+ "beginFragmentShaderOrderingINTEL(",
+ "beginInvocationInterlockARB(",
+ "endInvocationInterlockARB(",
+ "memoryBarrier(",
+ "memoryBarrierAtomicCounter(",
+ "memoryBarrierBuffer(",
+ "memoryBarrierImage(",
+ "barrier(",
+ "memoryBarrierShared(",
+ "groupMemoryBarrier(",
+ "EmitVertex(",
+ "EndPrimitive(",
+ "subpassLoad(01j",
+ "subpassLoad(01k",
+ "subpassLoad(01l",
+ "subpassLoad(01m00D",
+ "subpassLoad(01n00D",
+ "subpassLoad(01o00D",
+ "gl_DepthRangeParameters",
+ "gl_DepthRange",
+ "gl_NumSamples",
+ "gl_MaxVertexAttribs",
+ "gl_MaxVertexUniformVectors",
+ "gl_MaxVertexTextureImageUnits",
+ "gl_MaxCombinedTextureImageUnits",
+ "gl_MaxTextureImageUnits",
+ "gl_MaxFragmentUniformVectors",
+ "gl_MaxVaryingVectors",
+ "gl_MaxDrawBuffers",
+ "gl_MaxDualSourceDrawBuffersEXT",
+ "gl_MaxVertexOutputVectors",
+ "gl_MaxFragmentInputVectors",
+ "gl_MinProgramTexelOffset",
+ "gl_MaxProgramTexelOffset",
+ "gl_MaxImageUnits",
+ "gl_MaxVertexImageUniforms",
+ "gl_MaxFragmentImageUniforms",
+ "gl_MaxComputeImageUniforms",
+ "gl_MaxCombinedImageUniforms",
+ "gl_MaxCombinedShaderOutputResources",
+ "gl_MaxComputeWorkGroupCount",
+ "gl_MaxComputeWorkGroupSize",
+ "gl_MaxComputeUniformComponents",
+ "gl_MaxComputeTextureImageUnits",
+ "gl_MaxComputeAtomicCounters",
+ "gl_MaxComputeAtomicCounterBuffers",
+ "gl_MaxVertexAtomicCounters",
+ "gl_MaxFragmentAtomicCounters",
+ "gl_MaxCombinedAtomicCounters",
+ "gl_MaxAtomicCounterBindings",
+ "gl_MaxVertexAtomicCounterBuffers",
+ "gl_MaxFragmentAtomicCounterBuffers",
+ "gl_MaxCombinedAtomicCounterBuffers",
+ "gl_MaxAtomicCounterBufferSize",
+ "gl_MaxGeometryInputComponents",
+ "gl_MaxGeometryOutputComponents",
+ "gl_MaxGeometryImageUniforms",
+ "gl_MaxGeometryTextureImageUnits",
+ "gl_MaxGeometryOutputVertices",
+ "gl_MaxGeometryTotalOutputComponents",
+ "gl_MaxGeometryUniformComponents",
+ "gl_MaxGeometryAtomicCounters",
+ "gl_MaxGeometryAtomicCounterBuffers",
+ "gl_MaxTessControlInputComponents",
+ "gl_MaxTessControlOutputComponents",
+ "gl_MaxTessControlTextureImageUnits",
+ "gl_MaxTessControlUniformComponents",
+ "gl_MaxTessControlTotalOutputComponents",
+ "gl_MaxTessControlImageUniforms",
+ "gl_MaxTessControlAtomicCounters",
+ "gl_MaxTessControlAtomicCounterBuffers",
+ "gl_MaxTessPatchComponents",
+ "gl_MaxPatchVertices",
+ "gl_MaxTessGenLevel",
+ "gl_MaxTessEvaluationInputComponents",
+ "gl_MaxTessEvaluationOutputComponents",
+ "gl_MaxTessEvaluationTextureImageUnits",
+ "gl_MaxTessEvaluationUniformComponents",
+ "gl_MaxTessEvaluationImageUniforms",
+ "gl_MaxTessEvaluationAtomicCounters",
+ "gl_MaxTessEvaluationAtomicCounterBuffers",
+ "gl_MaxSamples",
+ "gl_MaxClipDistances",
+ "gl_MaxCullDistances",
+ "gl_MaxCombinedClipAndCullDistances",
+ "gl_FragCoord",
+ "gl_FrontFacing",
+ "gl_PointCoord",
+ "gl_FragColor",
+ "gl_FragData",
+ "gl_FragDepth",
+ "gl_HelperInvocation",
+ "gl_SecondaryFragColorEXT",
+ "gl_SecondaryFragDataEXT",
+ "gl_FragDepthEXT",
+ "gl_LastFragData",
+ "gl_LastFragColor",
+ "gl_LastFragColorARM",
+ "gl_PrimitiveID",
+ "gl_Layer",
+ "gl_SampleID",
+ "gl_SamplePosition",
+ "gl_SampleMaskIn",
+ "gl_SampleMask",
+ "gl_CullDistance",
+ "gl_ClipDistance",
+ "gl_Position",
+ "gl_PointSize",
+ "gl_InstanceID",
+ "",
+ "gl_VertexID",
+ "",
+ "",
+ "gl_DrawID",
+ "gl_BaseVertex",
+ "gl_BaseInstance",
+ "angle_BaseVertex",
+ "angle_BaseInstance",
+ "gl_NumWorkGroups",
+ "gl_WorkGroupSize",
+ "gl_WorkGroupID",
+ "gl_LocalInvocationID",
+ "gl_GlobalInvocationID",
+ "gl_LocalInvocationIndex",
+ "gl_PrimitiveIDIn",
+ "gl_InvocationID",
+ "gl_PerVertex",
+ "gl_in",
+ "gl_PatchVerticesIn",
+ "gl_TessLevelOuter",
+ "gl_TessLevelInner",
+ "gl_out",
+ "gl_BoundingBox",
+ "gl_BoundingBoxEXT",
+ "gl_BoundingBoxOES",
+ "gl_TessCoord",
+ "gl_ViewID_OVR"};
+
+// Flat array of offsets from a symbol into the rules table.
+constexpr uint16_t kMangledOffsets[] = {
+ 0, // radians_00B
+ 1, // radians_10B
+ 2, // radians_20B
+ 3, // radians_30B
+ 4, // degrees_00B
+ 5, // degrees_10B
+ 6, // degrees_20B
+ 7, // degrees_30B
+ 8, // sin_00B
+ 9, // sin_10B
+ 10, // sin_20B
+ 11, // sin_30B
+ 12, // cos_00B
+ 13, // cos_10B
+ 14, // cos_20B
+ 15, // cos_30B
+ 16, // tan_00B
+ 17, // tan_10B
+ 18, // tan_20B
+ 19, // tan_30B
+ 20, // asin_00B
+ 21, // asin_10B
+ 22, // asin_20B
+ 23, // asin_30B
+ 24, // acos_00B
+ 25, // acos_10B
+ 26, // acos_20B
+ 27, // acos_30B
+ 28, // atan_00B00B
+ 29, // atan_10B10B
+ 30, // atan_20B20B
+ 31, // atan_30B30B
+ 32, // atan_00B
+ 33, // atan_10B
+ 34, // atan_20B
+ 35, // atan_30B
+ 36, // sinh_00B
+ 37, // sinh_10B
+ 38, // sinh_20B
+ 39, // sinh_30B
+ 40, // cosh_00B
+ 41, // cosh_10B
+ 42, // cosh_20B
+ 43, // cosh_30B
+ 44, // tanh_00B
+ 45, // tanh_10B
+ 46, // tanh_20B
+ 47, // tanh_30B
+ 48, // asinh_00B
+ 49, // asinh_10B
+ 50, // asinh_20B
+ 51, // asinh_30B
+ 52, // acosh_00B
+ 53, // acosh_10B
+ 54, // acosh_20B
+ 55, // acosh_30B
+ 56, // atanh_00B
+ 57, // atanh_10B
+ 58, // atanh_20B
+ 59, // atanh_30B
+ 60, // pow_00B00B
+ 61, // pow_10B10B
+ 62, // pow_20B20B
+ 63, // pow_30B30B
+ 64, // exp_00B
+ 65, // exp_10B
+ 66, // exp_20B
+ 67, // exp_30B
+ 68, // log_00B
+ 69, // log_10B
+ 70, // log_20B
+ 71, // log_30B
+ 72, // exp2_00B
+ 73, // exp2_10B
+ 74, // exp2_20B
+ 75, // exp2_30B
+ 76, // log2_00B
+ 77, // log2_10B
+ 78, // log2_20B
+ 79, // log2_30B
+ 80, // sqrt_00B
+ 81, // sqrt_10B
+ 82, // sqrt_20B
+ 83, // sqrt_30B
+ 84, // inversesqrt_00B
+ 85, // inversesqrt_10B
+ 86, // inversesqrt_20B
+ 87, // inversesqrt_30B
+ 88, // abs_00B
+ 89, // abs_10B
+ 90, // abs_20B
+ 91, // abs_30B
+ 92, // abs_00D
+ 93, // abs_10D
+ 94, // abs_20D
+ 95, // abs_30D
+ 96, // sign_00B
+ 97, // sign_10B
+ 98, // sign_20B
+ 99, // sign_30B
+ 100, // sign_00D
+ 101, // sign_10D
+ 102, // sign_20D
+ 103, // sign_30D
+ 104, // floor_00B
+ 105, // floor_10B
+ 106, // floor_20B
+ 107, // floor_30B
+ 108, // trunc_00B
+ 109, // trunc_10B
+ 110, // trunc_20B
+ 111, // trunc_30B
+ 112, // round_00B
+ 113, // round_10B
+ 114, // round_20B
+ 115, // round_30B
+ 116, // roundEven_00B
+ 117, // roundEven_10B
+ 118, // roundEven_20B
+ 119, // roundEven_30B
+ 120, // ceil_00B
+ 121, // ceil_10B
+ 122, // ceil_20B
+ 123, // ceil_30B
+ 124, // fract_00B
+ 125, // fract_10B
+ 126, // fract_20B
+ 127, // fract_30B
+ 128, // mod_00B00B
+ 129, // mod_10B00B
+ 130, // mod_20B00B
+ 131, // mod_30B00B
+ 132, // mod_10B10B
+ 133, // mod_20B20B
+ 134, // mod_30B30B
+ 135, // min_00B00B
+ 136, // min_10B00B
+ 137, // min_20B00B
+ 138, // min_30B00B
+ 139, // min_10B10B
+ 140, // min_20B20B
+ 141, // min_30B30B
+ 142, // min_00D00D
+ 143, // min_10D10D
+ 144, // min_20D20D
+ 145, // min_30D30D
+ 146, // min_10D00D
+ 147, // min_20D00D
+ 148, // min_30D00D
+ 149, // min_00E00E
+ 150, // min_10E10E
+ 151, // min_20E20E
+ 152, // min_30E30E
+ 153, // min_10E00E
+ 154, // min_20E00E
+ 155, // min_30E00E
+ 156, // max_00B00B
+ 157, // max_10B00B
+ 158, // max_20B00B
+ 159, // max_30B00B
+ 160, // max_10B10B
+ 161, // max_20B20B
+ 162, // max_30B30B
+ 163, // max_00D00D
+ 164, // max_10D10D
+ 165, // max_20D20D
+ 166, // max_30D30D
+ 167, // max_10D00D
+ 168, // max_20D00D
+ 169, // max_30D00D
+ 170, // max_00E00E
+ 171, // max_10E10E
+ 172, // max_20E20E
+ 173, // max_30E30E
+ 174, // max_10E00E
+ 175, // max_20E00E
+ 176, // max_30E00E
+ 177, // clamp_00B00B00B
+ 178, // clamp_10B00B00B
+ 179, // clamp_20B00B00B
+ 180, // clamp_30B00B00B
+ 181, // clamp_10B10B10B
+ 182, // clamp_20B20B20B
+ 183, // clamp_30B30B30B
+ 184, // clamp_00D00D00D
+ 185, // clamp_10D00D00D
+ 186, // clamp_20D00D00D
+ 187, // clamp_30D00D00D
+ 188, // clamp_10D10D10D
+ 189, // clamp_20D20D20D
+ 190, // clamp_30D30D30D
+ 191, // clamp_00E00E00E
+ 192, // clamp_10E00E00E
+ 193, // clamp_20E00E00E
+ 194, // clamp_30E00E00E
+ 195, // clamp_10E10E10E
+ 196, // clamp_20E20E20E
+ 197, // clamp_30E30E30E
+ 198, // mix_00B00B00B
+ 199, // mix_10B10B00B
+ 200, // mix_20B20B00B
+ 201, // mix_30B30B00B
+ 202, // mix_10B10B10B
+ 203, // mix_20B20B20B
+ 204, // mix_30B30B30B
+ 205, // mix_00B00B00F
+ 206, // mix_10B10B10F
+ 207, // mix_20B20B20F
+ 208, // mix_30B30B30F
+ 209, // mix_00D00D00F
+ 210, // mix_10D10D10F
+ 211, // mix_20D20D20F
+ 212, // mix_30D30D30F
+ 213, // mix_00E00E00F
+ 214, // mix_10E10E10F
+ 215, // mix_20E20E20F
+ 216, // mix_30E30E30F
+ 217, // mix_00F00F00F
+ 218, // mix_10F10F10F
+ 219, // mix_20F20F20F
+ 220, // mix_30F30F30F
+ 221, // step_00B00B
+ 222, // step_10B10B
+ 223, // step_20B20B
+ 224, // step_30B30B
+ 225, // step_00B10B
+ 226, // step_00B20B
+ 227, // step_00B30B
+ 228, // smoothstep_00B00B00B
+ 229, // smoothstep_10B10B10B
+ 230, // smoothstep_20B20B20B
+ 231, // smoothstep_30B30B30B
+ 232, // smoothstep_00B00B10B
+ 233, // smoothstep_00B00B20B
+ 234, // smoothstep_00B00B30B
+ 235, // modf_00B00B
+ 236, // modf_10B10B
+ 237, // modf_20B20B
+ 238, // modf_30B30B
+ 239, // isnan_00B
+ 240, // isnan_10B
+ 241, // isnan_20B
+ 242, // isnan_30B
+ 243, // isinf_00B
+ 244, // isinf_10B
+ 245, // isinf_20B
+ 246, // isinf_30B
+ 247, // floatBitsToInt_00B
+ 248, // floatBitsToInt_10B
+ 249, // floatBitsToInt_20B
+ 250, // floatBitsToInt_30B
+ 251, // floatBitsToUint_00B
+ 252, // floatBitsToUint_10B
+ 253, // floatBitsToUint_20B
+ 254, // floatBitsToUint_30B
+ 255, // intBitsToFloat_00D
+ 256, // intBitsToFloat_10D
+ 257, // intBitsToFloat_20D
+ 258, // intBitsToFloat_30D
+ 259, // uintBitsToFloat_00E
+ 260, // uintBitsToFloat_10E
+ 261, // uintBitsToFloat_20E
+ 262, // uintBitsToFloat_30E
+ 263, // fma_00B00B00B
+ 265, // fma_10B10B10B
+ 267, // fma_20B20B20B
+ 269, // fma_30B30B30B
+ 271, // frexp_00B00D
+ 272, // frexp_10B10D
+ 273, // frexp_20B20D
+ 274, // frexp_30B30D
+ 275, // ldexp_00B00D
+ 276, // ldexp_10B10D
+ 277, // ldexp_20B20D
+ 278, // ldexp_30B30D
+ 279, // packSnorm2x16_10B
+ 280, // packHalf2x16_10B
+ 281, // unpackSnorm2x16_00E
+ 282, // unpackHalf2x16_00E
+ 283, // packUnorm2x16_10B
+ 284, // unpackUnorm2x16_00E
+ 285, // packUnorm4x8_30B
+ 286, // packSnorm4x8_30B
+ 287, // unpackUnorm4x8_00E
+ 288, // unpackSnorm4x8_00E
+ 289, // length_00B
+ 290, // length_10B
+ 291, // length_20B
+ 292, // length_30B
+ 293, // distance_00B00B
+ 294, // distance_10B10B
+ 295, // distance_20B20B
+ 296, // distance_30B30B
+ 297, // dot_00B00B
+ 298, // dot_10B10B
+ 299, // dot_20B20B
+ 300, // dot_30B30B
+ 301, // cross_20B20B
+ 302, // normalize_00B
+ 303, // normalize_10B
+ 304, // normalize_20B
+ 305, // normalize_30B
+ 306, // faceforward_00B00B00B
+ 307, // faceforward_10B10B10B
+ 308, // faceforward_20B20B20B
+ 309, // faceforward_30B30B30B
+ 310, // reflect_00B00B
+ 311, // reflect_10B10B
+ 312, // reflect_20B20B
+ 313, // reflect_30B30B
+ 314, // refract_00B00B00B
+ 315, // refract_10B10B00B
+ 316, // refract_20B20B00B
+ 317, // refract_30B30B00B
+ 318, // matrixCompMult_50B50B
+ 319, // matrixCompMult_A0BA0B
+ 320, // matrixCompMult_F0BF0B
+ 321, // matrixCompMult_90B90B
+ 322, // matrixCompMult_60B60B
+ 323, // matrixCompMult_D0BD0B
+ 324, // matrixCompMult_70B70B
+ 325, // matrixCompMult_E0BE0B
+ 326, // matrixCompMult_B0BB0B
+ 327, // outerProduct_10B10B
+ 328, // outerProduct_20B20B
+ 329, // outerProduct_30B30B
+ 330, // outerProduct_20B10B
+ 331, // outerProduct_10B20B
+ 332, // outerProduct_30B10B
+ 333, // outerProduct_10B30B
+ 334, // outerProduct_30B20B
+ 335, // outerProduct_20B30B
+ 336, // transpose_50B
+ 337, // transpose_A0B
+ 338, // transpose_F0B
+ 339, // transpose_60B
+ 340, // transpose_90B
+ 341, // transpose_70B
+ 342, // transpose_D0B
+ 343, // transpose_B0B
+ 344, // transpose_E0B
+ 345, // determinant_50B
+ 346, // determinant_A0B
+ 347, // determinant_F0B
+ 348, // inverse_50B
+ 349, // inverse_A0B
+ 350, // inverse_F0B
+ 351, // lessThan_10B10B
+ 352, // lessThan_20B20B
+ 353, // lessThan_30B30B
+ 354, // lessThan_10D10D
+ 355, // lessThan_20D20D
+ 356, // lessThan_30D30D
+ 357, // lessThan_10E10E
+ 358, // lessThan_20E20E
+ 359, // lessThan_30E30E
+ 360, // lessThanEqual_10B10B
+ 361, // lessThanEqual_20B20B
+ 362, // lessThanEqual_30B30B
+ 363, // lessThanEqual_10D10D
+ 364, // lessThanEqual_20D20D
+ 365, // lessThanEqual_30D30D
+ 366, // lessThanEqual_10E10E
+ 367, // lessThanEqual_20E20E
+ 368, // lessThanEqual_30E30E
+ 369, // greaterThan_10B10B
+ 370, // greaterThan_20B20B
+ 371, // greaterThan_30B30B
+ 372, // greaterThan_10D10D
+ 373, // greaterThan_20D20D
+ 374, // greaterThan_30D30D
+ 375, // greaterThan_10E10E
+ 376, // greaterThan_20E20E
+ 377, // greaterThan_30E30E
+ 378, // greaterThanEqual_10B10B
+ 379, // greaterThanEqual_20B20B
+ 380, // greaterThanEqual_30B30B
+ 381, // greaterThanEqual_10D10D
+ 382, // greaterThanEqual_20D20D
+ 383, // greaterThanEqual_30D30D
+ 384, // greaterThanEqual_10E10E
+ 385, // greaterThanEqual_20E20E
+ 386, // greaterThanEqual_30E30E
+ 387, // equal_10B10B
+ 388, // equal_20B20B
+ 389, // equal_30B30B
+ 390, // equal_10D10D
+ 391, // equal_20D20D
+ 392, // equal_30D30D
+ 393, // equal_10E10E
+ 394, // equal_20E20E
+ 395, // equal_30E30E
+ 396, // equal_10F10F
+ 397, // equal_20F20F
+ 398, // equal_30F30F
+ 399, // notEqual_10B10B
+ 400, // notEqual_20B20B
+ 401, // notEqual_30B30B
+ 402, // notEqual_10D10D
+ 403, // notEqual_20D20D
+ 404, // notEqual_30D30D
+ 405, // notEqual_10E10E
+ 406, // notEqual_20E20E
+ 407, // notEqual_30E30E
+ 408, // notEqual_10F10F
+ 409, // notEqual_20F20F
+ 410, // notEqual_30F30F
+ 411, // any_10F
+ 412, // any_20F
+ 413, // any_30F
+ 414, // all_10F
+ 415, // all_20F
+ 416, // all_30F
+ 417, // not_10F
+ 418, // not_20F
+ 419, // not_30F
+ 420, // bitfieldExtract_00D00D00D
+ 421, // bitfieldExtract_10D00D00D
+ 422, // bitfieldExtract_20D00D00D
+ 423, // bitfieldExtract_30D00D00D
+ 424, // bitfieldExtract_00E00D00D
+ 425, // bitfieldExtract_10E00D00D
+ 426, // bitfieldExtract_20E00D00D
+ 427, // bitfieldExtract_30E00D00D
+ 428, // bitfieldInsert_00D00D00D00D
+ 429, // bitfieldInsert_10D10D00D00D
+ 430, // bitfieldInsert_20D20D00D00D
+ 431, // bitfieldInsert_30D30D00D00D
+ 432, // bitfieldInsert_00E00E00D00D
+ 433, // bitfieldInsert_10E10E00D00D
+ 434, // bitfieldInsert_20E20E00D00D
+ 435, // bitfieldInsert_30E30E00D00D
+ 436, // bitfieldReverse_00D
+ 437, // bitfieldReverse_10D
+ 438, // bitfieldReverse_20D
+ 439, // bitfieldReverse_30D
+ 440, // bitfieldReverse_00E
+ 441, // bitfieldReverse_10E
+ 442, // bitfieldReverse_20E
+ 443, // bitfieldReverse_30E
+ 444, // bitCount_00D
+ 445, // bitCount_10D
+ 446, // bitCount_20D
+ 447, // bitCount_30D
+ 448, // bitCount_00E
+ 449, // bitCount_10E
+ 450, // bitCount_20E
+ 451, // bitCount_30E
+ 452, // findLSB_00D
+ 453, // findLSB_10D
+ 454, // findLSB_20D
+ 455, // findLSB_30D
+ 456, // findLSB_00E
+ 457, // findLSB_10E
+ 458, // findLSB_20E
+ 459, // findLSB_30E
+ 460, // findMSB_00D
+ 461, // findMSB_10D
+ 462, // findMSB_20D
+ 463, // findMSB_30D
+ 464, // findMSB_00E
+ 465, // findMSB_10E
+ 466, // findMSB_20E
+ 467, // findMSB_30E
+ 468, // uaddCarry_00E00E00E
+ 469, // uaddCarry_10E10E10E
+ 470, // uaddCarry_20E20E20E
+ 471, // uaddCarry_30E30E30E
+ 472, // usubBorrow_00E00E00E
+ 473, // usubBorrow_10E10E10E
+ 474, // usubBorrow_20E20E20E
+ 475, // usubBorrow_30E30E30E
+ 476, // umulExtended_00E00E00E00E
+ 477, // umulExtended_10E10E10E10E
+ 478, // umulExtended_20E20E20E20E
+ 479, // umulExtended_30E30E30E30E
+ 480, // imulExtended_00D00D00D00D
+ 481, // imulExtended_10D10D10D10D
+ 482, // imulExtended_20D20D20D20D
+ 483, // imulExtended_30D30D30D30D
+ 484, // texture2D_00I10B
+ 485, // texture2DProj_00I20B
+ 486, // texture2DProj_00I30B
+ 487, // textureCube_00K20B
+ 488, // texture3D_00J20B
+ 489, // texture3DProj_00J30B
+ 490, // shadow2DEXT_00d20B
+ 491, // shadow2DProjEXT_00d30B
+ 492, // texture2D_00M10B
+ 494, // texture2DProj_00M20B
+ 496, // texture2DProj_00M30B
+ 498, // texture2DRect_00O10B
+ 499, // texture2DRectProj_00O20B
+ 500, // texture2DRectProj_00O30B
+ 501, // texture2DGradEXT_00I10B10B10B
+ 502, // texture2DProjGradEXT_00I20B10B10B
+ 503, // texture2DProjGradEXT_00I30B10B10B
+ 504, // textureCubeGradEXT_00K20B20B20B
+ 505, // textureVideoWEBGL_00y10B
+ 506, // texture2D_00I10B00B
+ 507, // texture2DProj_00I20B00B
+ 508, // texture2DProj_00I30B00B
+ 509, // textureCube_00K20B00B
+ 510, // texture3D_00J20B00B
+ 511, // texture3DProj_00J30B00B
+ 512, // texture3DLod_00J20B00B
+ 513, // texture3DProjLod_00J30B00B
+ 514, // texture2DLod_00I10B00B
+ 515, // texture2DProjLod_00I20B00B
+ 516, // texture2DProjLod_00I30B00B
+ 517, // textureCubeLod_00K20B00B
+ 518, // texture2DLodEXT_00I10B00B
+ 519, // texture2DProjLodEXT_00I20B00B
+ 520, // texture2DProjLodEXT_00I30B00B
+ 521, // textureCubeLodEXT_00K20B00B
+ 522, // texture_00I10B
+ 523, // texture_00R10B
+ 524, // texture_00X10B
+ 525, // texture_00J20B
+ 526, // texture_00S20B
+ 527, // texture_00Y20B
+ 528, // texture_00K20B
+ 529, // texture_00T20B
+ 530, // texture_00Z20B
+ 531, // texture_00L20B
+ 532, // texture_00U20B
+ 533, // texture_00a20B
+ 534, // texture_00d20B
+ 535, // texture_00e30B
+ 536, // texture_00f30B
+ 537, // texture_00k30B
+ 540, // texture_00s30B
+ 543, // texture_00x30B
+ 546, // texture_00l30B00B
+ 549, // texture_00M10B
+ 550, // texture_00N10B
+ 551, // texture_00O10B
+ 552, // texture_00y10B
+ 553, // textureProj_00I20B
+ 554, // textureProj_00R20B
+ 555, // textureProj_00X20B
+ 556, // textureProj_00I30B
+ 557, // textureProj_00R30B
+ 558, // textureProj_00X30B
+ 559, // textureProj_00J30B
+ 560, // textureProj_00S30B
+ 561, // textureProj_00Y30B
+ 562, // textureProj_00d30B
+ 563, // textureProj_00M20B
+ 564, // textureProj_00M30B
+ 565, // textureProj_00N20B
+ 566, // textureProj_00N30B
+ 567, // textureProj_00O20B
+ 568, // textureProj_00O30B
+ 569, // textureLod_00I10B00B
+ 570, // textureLod_00R10B00B
+ 571, // textureLod_00X10B00B
+ 572, // textureLod_00J20B00B
+ 573, // textureLod_00S20B00B
+ 574, // textureLod_00Y20B00B
+ 575, // textureLod_00K20B00B
+ 576, // textureLod_00T20B00B
+ 577, // textureLod_00Z20B00B
+ 578, // textureLod_00L20B00B
+ 579, // textureLod_00U20B00B
+ 580, // textureLod_00a20B00B
+ 581, // textureLod_00d20B00B
+ 582, // textureLod_00k30B00B
+ 585, // textureLod_00s30B00B
+ 588, // textureLod_00x30B00B
+ 591, // textureSize_00I00D
+ 592, // textureSize_00R00D
+ 593, // textureSize_00X00D
+ 594, // textureSize_00J00D
+ 595, // textureSize_00S00D
+ 596, // textureSize_00Y00D
+ 597, // textureSize_00K00D
+ 598, // textureSize_00T00D
+ 599, // textureSize_00Z00D
+ 600, // textureSize_00L00D
+ 601, // textureSize_00U00D
+ 602, // textureSize_00a00D
+ 603, // textureSize_00d00D
+ 604, // textureSize_00e00D
+ 605, // textureSize_00f00D
+ 606, // textureSize_00k00D
+ 609, // textureSize_00s00D
+ 612, // textureSize_00x00D
+ 615, // textureSize_00l00D
+ 618, // textureSize_00j
+ 621, // textureSize_00r
+ 624, // textureSize_00w
+ 627, // textureSize_00P
+ 629, // textureSize_00V
+ 631, // textureSize_00b
+ 633, // textureSize_00Q
+ 635, // textureSize_00W
+ 637, // textureSize_00c
+ 639, // textureSize_00M00D
+ 640, // textureSize_00N00D
+ 641, // textureProjLod_00I20B00B
+ 642, // textureProjLod_00R20B00B
+ 643, // textureProjLod_00X20B00B
+ 644, // textureProjLod_00I30B00B
+ 645, // textureProjLod_00R30B00B
+ 646, // textureProjLod_00X30B00B
+ 647, // textureProjLod_00J30B00B
+ 648, // textureProjLod_00S30B00B
+ 649, // textureProjLod_00Y30B00B
+ 650, // textureProjLod_00d30B00B
+ 651, // texelFetch_00I10D00D
+ 652, // texelFetch_00R10D00D
+ 653, // texelFetch_00X10D00D
+ 654, // texelFetch_00J20D00D
+ 655, // texelFetch_00S20D00D
+ 656, // texelFetch_00Y20D00D
+ 657, // texelFetch_00L20D00D
+ 658, // texelFetch_00U20D00D
+ 659, // texelFetch_00a20D00D
+ 660, // texelFetch_00j00D
+ 663, // texelFetch_00r00D
+ 666, // texelFetch_00w00D
+ 669, // texelFetch_00P10D00D
+ 671, // texelFetch_00V10D00D
+ 673, // texelFetch_00b10D00D
+ 675, // texelFetch_00Q20D00D
+ 677, // texelFetch_00W20D00D
+ 679, // texelFetch_00c20D00D
+ 681, // texelFetch_00M10D00D
+ 682, // texelFetch_00N10D00D
+ 683, // textureGrad_00I10B10B10B
+ 684, // textureGrad_00R10B10B10B
+ 685, // textureGrad_00X10B10B10B
+ 686, // textureGrad_00J20B20B20B
+ 687, // textureGrad_00S20B20B20B
+ 688, // textureGrad_00Y20B20B20B
+ 689, // textureGrad_00K20B20B20B
+ 690, // textureGrad_00T20B20B20B
+ 691, // textureGrad_00Z20B20B20B
+ 692, // textureGrad_00d20B10B10B
+ 693, // textureGrad_00e30B20B20B
+ 694, // textureGrad_00L20B10B10B
+ 695, // textureGrad_00U20B10B10B
+ 696, // textureGrad_00a20B10B10B
+ 697, // textureGrad_00f30B10B10B
+ 698, // textureGrad_00k30B20B20B
+ 701, // textureGrad_00s30B20B20B
+ 704, // textureGrad_00x30B20B20B
+ 707, // textureProjGrad_00I20B10B10B
+ 708, // textureProjGrad_00R20B10B10B
+ 709, // textureProjGrad_00X20B10B10B
+ 710, // textureProjGrad_00I30B10B10B
+ 711, // textureProjGrad_00R30B10B10B
+ 712, // textureProjGrad_00X30B10B10B
+ 713, // textureProjGrad_00J30B20B20B
+ 714, // textureProjGrad_00S30B20B20B
+ 715, // textureProjGrad_00Y30B20B20B
+ 716, // textureProjGrad_00d30B10B10B
+ 717, // texture_00I10B00B
+ 718, // texture_00R10B00B
+ 719, // texture_00X10B00B
+ 720, // texture_00J20B00B
+ 721, // texture_00S20B00B
+ 722, // texture_00Y20B00B
+ 723, // texture_00K20B00B
+ 724, // texture_00T20B00B
+ 725, // texture_00Z20B00B
+ 726, // texture_00L20B00B
+ 727, // texture_00U20B00B
+ 728, // texture_00a20B00B
+ 729, // textureProj_00I20B00B
+ 730, // textureProj_00R20B00B
+ 731, // textureProj_00X20B00B
+ 732, // textureProj_00I30B00B
+ 733, // textureProj_00R30B00B
+ 734, // textureProj_00X30B00B
+ 735, // textureProj_00J30B00B
+ 736, // textureProj_00S30B00B
+ 737, // textureProj_00Y30B00B
+ 738, // texture_00d20B00B
+ 739, // texture_00e30B00B
+ 740, // textureProj_00d30B00B
+ 741, // texture_00k30B00B
+ 744, // texture_00s30B00B
+ 747, // texture_00x30B00B
+ 750, // texture_00M10B00B
+ 751, // textureProj_00M20B00B
+ 752, // textureProj_00M30B00B
+ 753, // texture_00N10B00B
+ 754, // textureProj_00N20B00B
+ 755, // textureProj_00N30B00B
+ 756, // textureOffset_00I10B10D
+ 757, // textureOffset_00R10B10D
+ 758, // textureOffset_00X10B10D
+ 759, // textureOffset_00J20B20D
+ 760, // textureOffset_00S20B20D
+ 761, // textureOffset_00Y20B20D
+ 762, // textureOffset_00d20B10D
+ 763, // textureOffset_00L20B10D
+ 764, // textureOffset_00U20B10D
+ 765, // textureOffset_00a20B10D
+ 766, // textureProjOffset_00I20B10D
+ 767, // textureProjOffset_00R20B10D
+ 768, // textureProjOffset_00X20B10D
+ 769, // textureProjOffset_00I30B10D
+ 770, // textureProjOffset_00R30B10D
+ 771, // textureProjOffset_00X30B10D
+ 772, // textureProjOffset_00J30B20D
+ 773, // textureProjOffset_00S30B20D
+ 774, // textureProjOffset_00Y30B20D
+ 775, // textureProjOffset_00d30B10D
+ 776, // textureLodOffset_00I10B00B10D
+ 777, // textureLodOffset_00R10B00B10D
+ 778, // textureLodOffset_00X10B00B10D
+ 779, // textureLodOffset_00J20B00B20D
+ 780, // textureLodOffset_00S20B00B20D
+ 781, // textureLodOffset_00Y20B00B20D
+ 782, // textureLodOffset_00d20B00B10D
+ 783, // textureLodOffset_00L20B00B10D
+ 784, // textureLodOffset_00U20B00B10D
+ 785, // textureLodOffset_00a20B00B10D
+ 786, // textureProjLodOffset_00I20B00B10D
+ 787, // textureProjLodOffset_00R20B00B10D
+ 788, // textureProjLodOffset_00X20B00B10D
+ 789, // textureProjLodOffset_00I30B00B10D
+ 790, // textureProjLodOffset_00R30B00B10D
+ 791, // textureProjLodOffset_00X30B00B10D
+ 792, // textureProjLodOffset_00J30B00B20D
+ 793, // textureProjLodOffset_00S30B00B20D
+ 794, // textureProjLodOffset_00Y30B00B20D
+ 795, // textureProjLodOffset_00d30B00B10D
+ 796, // texelFetchOffset_00I10D00D10D
+ 797, // texelFetchOffset_00R10D00D10D
+ 798, // texelFetchOffset_00X10D00D10D
+ 799, // texelFetchOffset_00J20D00D20D
+ 800, // texelFetchOffset_00S20D00D20D
+ 801, // texelFetchOffset_00Y20D00D20D
+ 802, // texelFetchOffset_00L20D00D10D
+ 803, // texelFetchOffset_00U20D00D10D
+ 804, // texelFetchOffset_00a20D00D10D
+ 805, // textureGradOffset_00I10B10B10B10D
+ 806, // textureGradOffset_00R10B10B10B10D
+ 807, // textureGradOffset_00X10B10B10B10D
+ 808, // textureGradOffset_00J20B20B20B20D
+ 809, // textureGradOffset_00S20B20B20B20D
+ 810, // textureGradOffset_00Y20B20B20B20D
+ 811, // textureGradOffset_00d20B10B10B10D
+ 812, // textureGradOffset_00L20B10B10B10D
+ 813, // textureGradOffset_00U20B10B10B10D
+ 814, // textureGradOffset_00a20B10B10B10D
+ 815, // textureGradOffset_00f30B10B10B10D
+ 816, // textureProjGradOffset_00I20B10B10B10D
+ 817, // textureProjGradOffset_00R20B10B10B10D
+ 818, // textureProjGradOffset_00X20B10B10B10D
+ 819, // textureProjGradOffset_00I30B10B10B10D
+ 820, // textureProjGradOffset_00R30B10B10B10D
+ 821, // textureProjGradOffset_00X30B10B10B10D
+ 822, // textureProjGradOffset_00J30B20B20B20D
+ 823, // textureProjGradOffset_00S30B20B20B20D
+ 824, // textureProjGradOffset_00Y30B20B20B20D
+ 825, // textureProjGradOffset_00d30B10B10B10D
+ 826, // textureOffset_00I10B10D00B
+ 827, // textureOffset_00R10B10D00B
+ 828, // textureOffset_00X10B10D00B
+ 829, // textureOffset_00J20B20D00B
+ 830, // textureOffset_00S20B20D00B
+ 831, // textureOffset_00Y20B20D00B
+ 832, // textureOffset_00d20B10D00B
+ 833, // textureOffset_00L20B10D00B
+ 834, // textureOffset_00U20B10D00B
+ 835, // textureOffset_00a20B10D00B
+ 836, // textureProjOffset_00I20B10D00B
+ 837, // textureProjOffset_00R20B10D00B
+ 838, // textureProjOffset_00X20B10D00B
+ 839, // textureProjOffset_00I30B10D00B
+ 840, // textureProjOffset_00R30B10D00B
+ 841, // textureProjOffset_00X30B10D00B
+ 842, // textureProjOffset_00J30B20D00B
+ 843, // textureProjOffset_00S30B20D00B
+ 844, // textureProjOffset_00Y30B20D00B
+ 845, // textureProjOffset_00d30B10D00B
+ 846, // textureGather_00I10B
+ 847, // textureGather_00R10B
+ 848, // textureGather_00X10B
+ 849, // textureGather_00I10B00D
+ 850, // textureGather_00R10B00D
+ 851, // textureGather_00X10B00D
+ 852, // textureGather_00L20B
+ 853, // textureGather_00U20B
+ 854, // textureGather_00a20B
+ 855, // textureGather_00L20B00D
+ 856, // textureGather_00U20B00D
+ 857, // textureGather_00a20B00D
+ 858, // textureGather_00K20B
+ 859, // textureGather_00T20B
+ 860, // textureGather_00Z20B
+ 861, // textureGather_00K20B00D
+ 862, // textureGather_00T20B00D
+ 863, // textureGather_00Z20B00D
+ 864, // textureGather_00k30B
+ 867, // textureGather_00s30B
+ 870, // textureGather_00x30B
+ 873, // textureGather_00k30B00D
+ 876, // textureGather_00s30B00D
+ 879, // textureGather_00x30B00D
+ 882, // textureGather_00l30B00B
+ 885, // textureGather_00d10B
+ 886, // textureGather_00d10B00B
+ 887, // textureGather_00f20B
+ 888, // textureGather_00f20B00B
+ 889, // textureGather_00e20B
+ 890, // textureGather_00e20B00B
+ 891, // textureGatherOffset_00I10B10D
+ 892, // textureGatherOffset_00R10B10D
+ 893, // textureGatherOffset_00X10B10D
+ 894, // textureGatherOffset_00L20B10D
+ 895, // textureGatherOffset_00U20B10D
+ 896, // textureGatherOffset_00a20B10D
+ 897, // textureGatherOffset_00d10B00B10D
+ 898, // textureGatherOffset_00f20B00B10D
+ 899, // textureGatherOffset_00I10B10D00D
+ 900, // textureGatherOffset_00R10B10D00D
+ 901, // textureGatherOffset_00X10B10D00D
+ 902, // textureGatherOffset_00L20B10D00D
+ 903, // textureGatherOffset_00U20B10D00D
+ 904, // textureGatherOffset_00a20B10D00D
+ 905, // textureGatherOffsets_00I10B10Dx4
+ 907, // textureGatherOffsets_00R10B10Dx4
+ 909, // textureGatherOffsets_00X10B10Dx4
+ 911, // textureGatherOffsets_00L20B10Dx4
+ 913, // textureGatherOffsets_00U20B10Dx4
+ 915, // textureGatherOffsets_00a20B10Dx4
+ 917, // textureGatherOffsets_00d10B00B10Dx4
+ 919, // textureGatherOffsets_00f20B00B10Dx4
+ 921, // textureGatherOffsets_00I10B10Dx400D
+ 923, // textureGatherOffsets_00R10B10Dx400D
+ 925, // textureGatherOffsets_00X10B10Dx400D
+ 927, // textureGatherOffsets_00L20B10Dx400D
+ 929, // textureGatherOffsets_00U20B10Dx400D
+ 931, // textureGatherOffsets_00a20B10Dx400D
+ 933, // rgb_2_yuv_20B00H
+ 934, // yuv_2_rgb_20B00H
+ 935, // dFdx_00B
+ 937, // dFdx_10B
+ 939, // dFdx_20B
+ 941, // dFdx_30B
+ 943, // dFdy_00B
+ 945, // dFdy_10B
+ 947, // dFdy_20B
+ 949, // dFdy_30B
+ 951, // fwidth_00B
+ 953, // fwidth_10B
+ 955, // fwidth_20B
+ 957, // fwidth_30B
+ 959, // interpolateAtCentroid_00B
+ 961, // interpolateAtCentroid_10B
+ 963, // interpolateAtCentroid_20B
+ 965, // interpolateAtCentroid_30B
+ 967, // interpolateAtSample_00B00D
+ 969, // interpolateAtSample_10B00D
+ 971, // interpolateAtSample_20B00D
+ 973, // interpolateAtSample_30B00D
+ 975, // interpolateAtOffset_00B10B
+ 977, // interpolateAtOffset_10B10B
+ 979, // interpolateAtOffset_20B10B
+ 981, // interpolateAtOffset_30B10B
+ 983, // atomicCounter_00G
+ 984, // atomicCounterIncrement_00G
+ 985, // atomicCounterDecrement_00G
+ 986, // atomicAdd_00E00E
+ 987, // atomicAdd_00D00D
+ 988, // atomicMin_00E00E
+ 989, // atomicMin_00D00D
+ 990, // atomicMax_00E00E
+ 991, // atomicMax_00D00D
+ 992, // atomicAnd_00E00E
+ 993, // atomicAnd_00D00D
+ 994, // atomicOr_00E00E
+ 995, // atomicOr_00D00D
+ 996, // atomicXor_00E00E
+ 997, // atomicXor_00D00D
+ 998, // atomicExchange_00E00E
+ 999, // atomicExchange_00D00D
+ 1000, // atomicCompSwap_00E00E00E
+ 1001, // atomicCompSwap_00D00D00D
+ 1002, // imageSize_00z
+ 1003, // imageSize_01K
+ 1004, // imageSize_01V
+ 1005, // imageSize_01A
+ 1006, // imageSize_01L
+ 1007, // imageSize_01W
+ 1008, // imageSize_01B
+ 1009, // imageSize_01M
+ 1010, // imageSize_01X
+ 1011, // imageSize_01C
+ 1012, // imageSize_01N
+ 1013, // imageSize_01Y
+ 1014, // imageSize_01H
+ 1017, // imageSize_01S
+ 1020, // imageSize_01d
+ 1023, // imageSize_01J
+ 1026, // imageSize_01U
+ 1029, // imageSize_01f
+ 1032, // imageStore_00z10D30B
+ 1033, // imageStore_01K10D30D
+ 1034, // imageStore_01V10D30E
+ 1035, // imageStore_01A20D30B
+ 1036, // imageStore_01L20D30D
+ 1037, // imageStore_01W20D30E
+ 1038, // imageStore_01B20D30B
+ 1039, // imageStore_01M20D30D
+ 1040, // imageStore_01X20D30E
+ 1041, // imageStore_01C20D30B
+ 1042, // imageStore_01N20D30D
+ 1043, // imageStore_01Y20D30E
+ 1044, // imageStore_01H20D30B
+ 1047, // imageStore_01S20D30D
+ 1050, // imageStore_01d20D30E
+ 1053, // imageStore_01J00D30B
+ 1056, // imageStore_01U00D30D
+ 1059, // imageStore_01f00D30E
+ 1062, // imageLoad_00z10D
+ 1063, // imageLoad_01K10D
+ 1064, // imageLoad_01V10D
+ 1065, // imageLoad_01A20D
+ 1066, // imageLoad_01L20D
+ 1067, // imageLoad_01W20D
+ 1068, // imageLoad_01B20D
+ 1069, // imageLoad_01M20D
+ 1070, // imageLoad_01X20D
+ 1071, // imageLoad_01C20D
+ 1072, // imageLoad_01N20D
+ 1073, // imageLoad_01Y20D
+ 1074, // imageLoad_01H20D
+ 1077, // imageLoad_01S20D
+ 1080, // imageLoad_01d20D
+ 1083, // imageLoad_01J00D
+ 1086, // imageLoad_01U00D
+ 1089, // imageLoad_01f00D
+ 1092, // imageAtomicAdd_00z10D00E
+ 1094, // imageAtomicAdd_01K10D00E
+ 1096, // imageAtomicAdd_01V10D00E
+ 1098, // imageAtomicAdd_01A20D00E
+ 1100, // imageAtomicAdd_01L20D00E
+ 1102, // imageAtomicAdd_01W20D00E
+ 1104, // imageAtomicAdd_01C20D00E
+ 1106, // imageAtomicAdd_01N20D00E
+ 1108, // imageAtomicAdd_01Y20D00E
+ 1110, // imageAtomicAdd_01J00D00E
+ 1112, // imageAtomicAdd_01U00D00E
+ 1114, // imageAtomicAdd_01f00D00E
+ 1116, // imageAtomicAdd_01B20D00E
+ 1118, // imageAtomicAdd_01M20D00E
+ 1120, // imageAtomicAdd_01X20D00E
+ 1122, // imageAtomicAdd_01H20D00E
+ 1124, // imageAtomicAdd_01S20D00E
+ 1126, // imageAtomicAdd_01d20D00E
+ 1128, // imageAtomicAdd_01D00D00E
+ 1130, // imageAtomicAdd_01O00D00E
+ 1132, // imageAtomicAdd_01Z00D00E
+ 1134, // imageAtomicAdd_01E10D00E
+ 1136, // imageAtomicAdd_01P10D00E
+ 1138, // imageAtomicAdd_01a10D00E
+ 1140, // imageAtomicAdd_01I10D00E
+ 1142, // imageAtomicAdd_01T10D00E
+ 1144, // imageAtomicAdd_01e10D00E
+ 1146, // imageAtomicAdd_01F10D00D00E
+ 1148, // imageAtomicAdd_01Q10D00D00E
+ 1150, // imageAtomicAdd_01b10D00D00E
+ 1152, // imageAtomicAdd_01G20D00D00E
+ 1154, // imageAtomicAdd_01R20D00D00E
+ 1156, // imageAtomicAdd_01c20D00D00E
+ 1158, // imageAtomicAdd_00z10D00D
+ 1160, // imageAtomicAdd_01K10D00D
+ 1162, // imageAtomicAdd_01V10D00D
+ 1164, // imageAtomicAdd_01A20D00D
+ 1166, // imageAtomicAdd_01L20D00D
+ 1168, // imageAtomicAdd_01W20D00D
+ 1170, // imageAtomicAdd_01C20D00D
+ 1172, // imageAtomicAdd_01N20D00D
+ 1174, // imageAtomicAdd_01Y20D00D
+ 1176, // imageAtomicAdd_01J00D00D
+ 1178, // imageAtomicAdd_01U00D00D
+ 1180, // imageAtomicAdd_01f00D00D
+ 1182, // imageAtomicAdd_01B20D00D
+ 1184, // imageAtomicAdd_01M20D00D
+ 1186, // imageAtomicAdd_01X20D00D
+ 1188, // imageAtomicAdd_01H20D00D
+ 1190, // imageAtomicAdd_01S20D00D
+ 1192, // imageAtomicAdd_01d20D00D
+ 1194, // imageAtomicAdd_01D00D00D
+ 1196, // imageAtomicAdd_01O00D00D
+ 1198, // imageAtomicAdd_01Z00D00D
+ 1200, // imageAtomicAdd_01E10D00D
+ 1202, // imageAtomicAdd_01P10D00D
+ 1204, // imageAtomicAdd_01a10D00D
+ 1206, // imageAtomicAdd_01I10D00D
+ 1208, // imageAtomicAdd_01T10D00D
+ 1210, // imageAtomicAdd_01e10D00D
+ 1212, // imageAtomicAdd_01F10D00D00D
+ 1214, // imageAtomicAdd_01Q10D00D00D
+ 1216, // imageAtomicAdd_01b10D00D00D
+ 1218, // imageAtomicAdd_01G20D00D00D
+ 1220, // imageAtomicAdd_01R20D00D00D
+ 1222, // imageAtomicAdd_01c20D00D00D
+ 1224, // imageAtomicMin_00z10D00E
+ 1226, // imageAtomicMin_01K10D00E
+ 1228, // imageAtomicMin_01V10D00E
+ 1230, // imageAtomicMin_01A20D00E
+ 1232, // imageAtomicMin_01L20D00E
+ 1234, // imageAtomicMin_01W20D00E
+ 1236, // imageAtomicMin_01C20D00E
+ 1238, // imageAtomicMin_01N20D00E
+ 1240, // imageAtomicMin_01Y20D00E
+ 1242, // imageAtomicMin_01J00D00E
+ 1244, // imageAtomicMin_01U00D00E
+ 1246, // imageAtomicMin_01f00D00E
+ 1248, // imageAtomicMin_01B20D00E
+ 1250, // imageAtomicMin_01M20D00E
+ 1252, // imageAtomicMin_01X20D00E
+ 1254, // imageAtomicMin_01H20D00E
+ 1256, // imageAtomicMin_01S20D00E
+ 1258, // imageAtomicMin_01d20D00E
+ 1260, // imageAtomicMin_01D00D00E
+ 1262, // imageAtomicMin_01O00D00E
+ 1264, // imageAtomicMin_01Z00D00E
+ 1266, // imageAtomicMin_01E10D00E
+ 1268, // imageAtomicMin_01P10D00E
+ 1270, // imageAtomicMin_01a10D00E
+ 1272, // imageAtomicMin_01I10D00E
+ 1274, // imageAtomicMin_01T10D00E
+ 1276, // imageAtomicMin_01e10D00E
+ 1278, // imageAtomicMin_01F10D00D00E
+ 1280, // imageAtomicMin_01Q10D00D00E
+ 1282, // imageAtomicMin_01b10D00D00E
+ 1284, // imageAtomicMin_01G20D00D00E
+ 1286, // imageAtomicMin_01R20D00D00E
+ 1288, // imageAtomicMin_01c20D00D00E
+ 1290, // imageAtomicMin_00z10D00D
+ 1292, // imageAtomicMin_01K10D00D
+ 1294, // imageAtomicMin_01V10D00D
+ 1296, // imageAtomicMin_01A20D00D
+ 1298, // imageAtomicMin_01L20D00D
+ 1300, // imageAtomicMin_01W20D00D
+ 1302, // imageAtomicMin_01C20D00D
+ 1304, // imageAtomicMin_01N20D00D
+ 1306, // imageAtomicMin_01Y20D00D
+ 1308, // imageAtomicMin_01J00D00D
+ 1310, // imageAtomicMin_01U00D00D
+ 1312, // imageAtomicMin_01f00D00D
+ 1314, // imageAtomicMin_01B20D00D
+ 1316, // imageAtomicMin_01M20D00D
+ 1318, // imageAtomicMin_01X20D00D
+ 1320, // imageAtomicMin_01H20D00D
+ 1322, // imageAtomicMin_01S20D00D
+ 1324, // imageAtomicMin_01d20D00D
+ 1326, // imageAtomicMin_01D00D00D
+ 1328, // imageAtomicMin_01O00D00D
+ 1330, // imageAtomicMin_01Z00D00D
+ 1332, // imageAtomicMin_01E10D00D
+ 1334, // imageAtomicMin_01P10D00D
+ 1336, // imageAtomicMin_01a10D00D
+ 1338, // imageAtomicMin_01I10D00D
+ 1340, // imageAtomicMin_01T10D00D
+ 1342, // imageAtomicMin_01e10D00D
+ 1344, // imageAtomicMin_01F10D00D00D
+ 1346, // imageAtomicMin_01Q10D00D00D
+ 1348, // imageAtomicMin_01b10D00D00D
+ 1350, // imageAtomicMin_01G20D00D00D
+ 1352, // imageAtomicMin_01R20D00D00D
+ 1354, // imageAtomicMin_01c20D00D00D
+ 1356, // imageAtomicMax_00z10D00E
+ 1358, // imageAtomicMax_01K10D00E
+ 1360, // imageAtomicMax_01V10D00E
+ 1362, // imageAtomicMax_01A20D00E
+ 1364, // imageAtomicMax_01L20D00E
+ 1366, // imageAtomicMax_01W20D00E
+ 1368, // imageAtomicMax_01C20D00E
+ 1370, // imageAtomicMax_01N20D00E
+ 1372, // imageAtomicMax_01Y20D00E
+ 1374, // imageAtomicMax_01J00D00E
+ 1376, // imageAtomicMax_01U00D00E
+ 1378, // imageAtomicMax_01f00D00E
+ 1380, // imageAtomicMax_01B20D00E
+ 1382, // imageAtomicMax_01M20D00E
+ 1384, // imageAtomicMax_01X20D00E
+ 1386, // imageAtomicMax_01H20D00E
+ 1388, // imageAtomicMax_01S20D00E
+ 1390, // imageAtomicMax_01d20D00E
+ 1392, // imageAtomicMax_01D00D00E
+ 1394, // imageAtomicMax_01O00D00E
+ 1396, // imageAtomicMax_01Z00D00E
+ 1398, // imageAtomicMax_01E10D00E
+ 1400, // imageAtomicMax_01P10D00E
+ 1402, // imageAtomicMax_01a10D00E
+ 1404, // imageAtomicMax_01I10D00E
+ 1406, // imageAtomicMax_01T10D00E
+ 1408, // imageAtomicMax_01e10D00E
+ 1410, // imageAtomicMax_01F10D00D00E
+ 1412, // imageAtomicMax_01Q10D00D00E
+ 1414, // imageAtomicMax_01b10D00D00E
+ 1416, // imageAtomicMax_01G20D00D00E
+ 1418, // imageAtomicMax_01R20D00D00E
+ 1420, // imageAtomicMax_01c20D00D00E
+ 1422, // imageAtomicMax_00z10D00D
+ 1424, // imageAtomicMax_01K10D00D
+ 1426, // imageAtomicMax_01V10D00D
+ 1428, // imageAtomicMax_01A20D00D
+ 1430, // imageAtomicMax_01L20D00D
+ 1432, // imageAtomicMax_01W20D00D
+ 1434, // imageAtomicMax_01C20D00D
+ 1436, // imageAtomicMax_01N20D00D
+ 1438, // imageAtomicMax_01Y20D00D
+ 1440, // imageAtomicMax_01J00D00D
+ 1442, // imageAtomicMax_01U00D00D
+ 1444, // imageAtomicMax_01f00D00D
+ 1446, // imageAtomicMax_01B20D00D
+ 1448, // imageAtomicMax_01M20D00D
+ 1450, // imageAtomicMax_01X20D00D
+ 1452, // imageAtomicMax_01H20D00D
+ 1454, // imageAtomicMax_01S20D00D
+ 1456, // imageAtomicMax_01d20D00D
+ 1458, // imageAtomicMax_01D00D00D
+ 1460, // imageAtomicMax_01O00D00D
+ 1462, // imageAtomicMax_01Z00D00D
+ 1464, // imageAtomicMax_01E10D00D
+ 1466, // imageAtomicMax_01P10D00D
+ 1468, // imageAtomicMax_01a10D00D
+ 1470, // imageAtomicMax_01I10D00D
+ 1472, // imageAtomicMax_01T10D00D
+ 1474, // imageAtomicMax_01e10D00D
+ 1476, // imageAtomicMax_01F10D00D00D
+ 1478, // imageAtomicMax_01Q10D00D00D
+ 1480, // imageAtomicMax_01b10D00D00D
+ 1482, // imageAtomicMax_01G20D00D00D
+ 1484, // imageAtomicMax_01R20D00D00D
+ 1486, // imageAtomicMax_01c20D00D00D
+ 1488, // imageAtomicAnd_00z10D00E
+ 1490, // imageAtomicAnd_01K10D00E
+ 1492, // imageAtomicAnd_01V10D00E
+ 1494, // imageAtomicAnd_01A20D00E
+ 1496, // imageAtomicAnd_01L20D00E
+ 1498, // imageAtomicAnd_01W20D00E
+ 1500, // imageAtomicAnd_01C20D00E
+ 1502, // imageAtomicAnd_01N20D00E
+ 1504, // imageAtomicAnd_01Y20D00E
+ 1506, // imageAtomicAnd_01J00D00E
+ 1508, // imageAtomicAnd_01U00D00E
+ 1510, // imageAtomicAnd_01f00D00E
+ 1512, // imageAtomicAnd_01B20D00E
+ 1514, // imageAtomicAnd_01M20D00E
+ 1516, // imageAtomicAnd_01X20D00E
+ 1518, // imageAtomicAnd_01H20D00E
+ 1520, // imageAtomicAnd_01S20D00E
+ 1522, // imageAtomicAnd_01d20D00E
+ 1524, // imageAtomicAnd_01D00D00E
+ 1526, // imageAtomicAnd_01O00D00E
+ 1528, // imageAtomicAnd_01Z00D00E
+ 1530, // imageAtomicAnd_01E10D00E
+ 1532, // imageAtomicAnd_01P10D00E
+ 1534, // imageAtomicAnd_01a10D00E
+ 1536, // imageAtomicAnd_01I10D00E
+ 1538, // imageAtomicAnd_01T10D00E
+ 1540, // imageAtomicAnd_01e10D00E
+ 1542, // imageAtomicAnd_01F10D00D00E
+ 1544, // imageAtomicAnd_01Q10D00D00E
+ 1546, // imageAtomicAnd_01b10D00D00E
+ 1548, // imageAtomicAnd_01G20D00D00E
+ 1550, // imageAtomicAnd_01R20D00D00E
+ 1552, // imageAtomicAnd_01c20D00D00E
+ 1554, // imageAtomicAnd_00z10D00D
+ 1556, // imageAtomicAnd_01K10D00D
+ 1558, // imageAtomicAnd_01V10D00D
+ 1560, // imageAtomicAnd_01A20D00D
+ 1562, // imageAtomicAnd_01L20D00D
+ 1564, // imageAtomicAnd_01W20D00D
+ 1566, // imageAtomicAnd_01C20D00D
+ 1568, // imageAtomicAnd_01N20D00D
+ 1570, // imageAtomicAnd_01Y20D00D
+ 1572, // imageAtomicAnd_01J00D00D
+ 1574, // imageAtomicAnd_01U00D00D
+ 1576, // imageAtomicAnd_01f00D00D
+ 1578, // imageAtomicAnd_01B20D00D
+ 1580, // imageAtomicAnd_01M20D00D
+ 1582, // imageAtomicAnd_01X20D00D
+ 1584, // imageAtomicAnd_01H20D00D
+ 1586, // imageAtomicAnd_01S20D00D
+ 1588, // imageAtomicAnd_01d20D00D
+ 1590, // imageAtomicAnd_01D00D00D
+ 1592, // imageAtomicAnd_01O00D00D
+ 1594, // imageAtomicAnd_01Z00D00D
+ 1596, // imageAtomicAnd_01E10D00D
+ 1598, // imageAtomicAnd_01P10D00D
+ 1600, // imageAtomicAnd_01a10D00D
+ 1602, // imageAtomicAnd_01I10D00D
+ 1604, // imageAtomicAnd_01T10D00D
+ 1606, // imageAtomicAnd_01e10D00D
+ 1608, // imageAtomicAnd_01F10D00D00D
+ 1610, // imageAtomicAnd_01Q10D00D00D
+ 1612, // imageAtomicAnd_01b10D00D00D
+ 1614, // imageAtomicAnd_01G20D00D00D
+ 1616, // imageAtomicAnd_01R20D00D00D
+ 1618, // imageAtomicAnd_01c20D00D00D
+ 1620, // imageAtomicOr_00z10D00E
+ 1622, // imageAtomicOr_01K10D00E
+ 1624, // imageAtomicOr_01V10D00E
+ 1626, // imageAtomicOr_01A20D00E
+ 1628, // imageAtomicOr_01L20D00E
+ 1630, // imageAtomicOr_01W20D00E
+ 1632, // imageAtomicOr_01C20D00E
+ 1634, // imageAtomicOr_01N20D00E
+ 1636, // imageAtomicOr_01Y20D00E
+ 1638, // imageAtomicOr_01J00D00E
+ 1640, // imageAtomicOr_01U00D00E
+ 1642, // imageAtomicOr_01f00D00E
+ 1644, // imageAtomicOr_01B20D00E
+ 1646, // imageAtomicOr_01M20D00E
+ 1648, // imageAtomicOr_01X20D00E
+ 1650, // imageAtomicOr_01H20D00E
+ 1652, // imageAtomicOr_01S20D00E
+ 1654, // imageAtomicOr_01d20D00E
+ 1656, // imageAtomicOr_01D00D00E
+ 1658, // imageAtomicOr_01O00D00E
+ 1660, // imageAtomicOr_01Z00D00E
+ 1662, // imageAtomicOr_01E10D00E
+ 1664, // imageAtomicOr_01P10D00E
+ 1666, // imageAtomicOr_01a10D00E
+ 1668, // imageAtomicOr_01I10D00E
+ 1670, // imageAtomicOr_01T10D00E
+ 1672, // imageAtomicOr_01e10D00E
+ 1674, // imageAtomicOr_01F10D00D00E
+ 1676, // imageAtomicOr_01Q10D00D00E
+ 1678, // imageAtomicOr_01b10D00D00E
+ 1680, // imageAtomicOr_01G20D00D00E
+ 1682, // imageAtomicOr_01R20D00D00E
+ 1684, // imageAtomicOr_01c20D00D00E
+ 1686, // imageAtomicOr_00z10D00D
+ 1688, // imageAtomicOr_01K10D00D
+ 1690, // imageAtomicOr_01V10D00D
+ 1692, // imageAtomicOr_01A20D00D
+ 1694, // imageAtomicOr_01L20D00D
+ 1696, // imageAtomicOr_01W20D00D
+ 1698, // imageAtomicOr_01C20D00D
+ 1700, // imageAtomicOr_01N20D00D
+ 1702, // imageAtomicOr_01Y20D00D
+ 1704, // imageAtomicOr_01J00D00D
+ 1706, // imageAtomicOr_01U00D00D
+ 1708, // imageAtomicOr_01f00D00D
+ 1710, // imageAtomicOr_01B20D00D
+ 1712, // imageAtomicOr_01M20D00D
+ 1714, // imageAtomicOr_01X20D00D
+ 1716, // imageAtomicOr_01H20D00D
+ 1718, // imageAtomicOr_01S20D00D
+ 1720, // imageAtomicOr_01d20D00D
+ 1722, // imageAtomicOr_01D00D00D
+ 1724, // imageAtomicOr_01O00D00D
+ 1726, // imageAtomicOr_01Z00D00D
+ 1728, // imageAtomicOr_01E10D00D
+ 1730, // imageAtomicOr_01P10D00D
+ 1732, // imageAtomicOr_01a10D00D
+ 1734, // imageAtomicOr_01I10D00D
+ 1736, // imageAtomicOr_01T10D00D
+ 1738, // imageAtomicOr_01e10D00D
+ 1740, // imageAtomicOr_01F10D00D00D
+ 1742, // imageAtomicOr_01Q10D00D00D
+ 1744, // imageAtomicOr_01b10D00D00D
+ 1746, // imageAtomicOr_01G20D00D00D
+ 1748, // imageAtomicOr_01R20D00D00D
+ 1750, // imageAtomicOr_01c20D00D00D
+ 1752, // imageAtomicXor_00z10D00E
+ 1754, // imageAtomicXor_01K10D00E
+ 1756, // imageAtomicXor_01V10D00E
+ 1758, // imageAtomicXor_01A20D00E
+ 1760, // imageAtomicXor_01L20D00E
+ 1762, // imageAtomicXor_01W20D00E
+ 1764, // imageAtomicXor_01C20D00E
+ 1766, // imageAtomicXor_01N20D00E
+ 1768, // imageAtomicXor_01Y20D00E
+ 1770, // imageAtomicXor_01J00D00E
+ 1772, // imageAtomicXor_01U00D00E
+ 1774, // imageAtomicXor_01f00D00E
+ 1776, // imageAtomicXor_01B20D00E
+ 1778, // imageAtomicXor_01M20D00E
+ 1780, // imageAtomicXor_01X20D00E
+ 1782, // imageAtomicXor_01H20D00E
+ 1784, // imageAtomicXor_01S20D00E
+ 1786, // imageAtomicXor_01d20D00E
+ 1788, // imageAtomicXor_01D00D00E
+ 1790, // imageAtomicXor_01O00D00E
+ 1792, // imageAtomicXor_01Z00D00E
+ 1794, // imageAtomicXor_01E10D00E
+ 1796, // imageAtomicXor_01P10D00E
+ 1798, // imageAtomicXor_01a10D00E
+ 1800, // imageAtomicXor_01I10D00E
+ 1802, // imageAtomicXor_01T10D00E
+ 1804, // imageAtomicXor_01e10D00E
+ 1806, // imageAtomicXor_01F10D00D00E
+ 1808, // imageAtomicXor_01Q10D00D00E
+ 1810, // imageAtomicXor_01b10D00D00E
+ 1812, // imageAtomicXor_01G20D00D00E
+ 1814, // imageAtomicXor_01R20D00D00E
+ 1816, // imageAtomicXor_01c20D00D00E
+ 1818, // imageAtomicXor_00z10D00D
+ 1820, // imageAtomicXor_01K10D00D
+ 1822, // imageAtomicXor_01V10D00D
+ 1824, // imageAtomicXor_01A20D00D
+ 1826, // imageAtomicXor_01L20D00D
+ 1828, // imageAtomicXor_01W20D00D
+ 1830, // imageAtomicXor_01C20D00D
+ 1832, // imageAtomicXor_01N20D00D
+ 1834, // imageAtomicXor_01Y20D00D
+ 1836, // imageAtomicXor_01J00D00D
+ 1838, // imageAtomicXor_01U00D00D
+ 1840, // imageAtomicXor_01f00D00D
+ 1842, // imageAtomicXor_01B20D00D
+ 1844, // imageAtomicXor_01M20D00D
+ 1846, // imageAtomicXor_01X20D00D
+ 1848, // imageAtomicXor_01H20D00D
+ 1850, // imageAtomicXor_01S20D00D
+ 1852, // imageAtomicXor_01d20D00D
+ 1854, // imageAtomicXor_01D00D00D
+ 1856, // imageAtomicXor_01O00D00D
+ 1858, // imageAtomicXor_01Z00D00D
+ 1860, // imageAtomicXor_01E10D00D
+ 1862, // imageAtomicXor_01P10D00D
+ 1864, // imageAtomicXor_01a10D00D
+ 1866, // imageAtomicXor_01I10D00D
+ 1868, // imageAtomicXor_01T10D00D
+ 1870, // imageAtomicXor_01e10D00D
+ 1872, // imageAtomicXor_01F10D00D00D
+ 1874, // imageAtomicXor_01Q10D00D00D
+ 1876, // imageAtomicXor_01b10D00D00D
+ 1878, // imageAtomicXor_01G20D00D00D
+ 1880, // imageAtomicXor_01R20D00D00D
+ 1882, // imageAtomicXor_01c20D00D00D
+ 1884, // imageAtomicExchange_00z10D00E
+ 1886, // imageAtomicExchange_01K10D00E
+ 1888, // imageAtomicExchange_01V10D00E
+ 1890, // imageAtomicExchange_01A20D00E
+ 1892, // imageAtomicExchange_01L20D00E
+ 1894, // imageAtomicExchange_01W20D00E
+ 1896, // imageAtomicExchange_01C20D00E
+ 1898, // imageAtomicExchange_01N20D00E
+ 1900, // imageAtomicExchange_01Y20D00E
+ 1902, // imageAtomicExchange_01J00D00E
+ 1904, // imageAtomicExchange_01U00D00E
+ 1906, // imageAtomicExchange_01f00D00E
+ 1908, // imageAtomicExchange_01B20D00E
+ 1910, // imageAtomicExchange_01M20D00E
+ 1912, // imageAtomicExchange_01X20D00E
+ 1914, // imageAtomicExchange_01H20D00E
+ 1916, // imageAtomicExchange_01S20D00E
+ 1918, // imageAtomicExchange_01d20D00E
+ 1920, // imageAtomicExchange_01D00D00E
+ 1922, // imageAtomicExchange_01O00D00E
+ 1924, // imageAtomicExchange_01Z00D00E
+ 1926, // imageAtomicExchange_01E10D00E
+ 1928, // imageAtomicExchange_01P10D00E
+ 1930, // imageAtomicExchange_01a10D00E
+ 1932, // imageAtomicExchange_01I10D00E
+ 1934, // imageAtomicExchange_01T10D00E
+ 1936, // imageAtomicExchange_01e10D00E
+ 1938, // imageAtomicExchange_01F10D00D00E
+ 1940, // imageAtomicExchange_01Q10D00D00E
+ 1942, // imageAtomicExchange_01b10D00D00E
+ 1944, // imageAtomicExchange_01G20D00D00E
+ 1946, // imageAtomicExchange_01R20D00D00E
+ 1948, // imageAtomicExchange_01c20D00D00E
+ 1950, // imageAtomicExchange_00z10D00D
+ 1952, // imageAtomicExchange_01K10D00D
+ 1954, // imageAtomicExchange_01V10D00D
+ 1956, // imageAtomicExchange_01A20D00D
+ 1958, // imageAtomicExchange_01L20D00D
+ 1960, // imageAtomicExchange_01W20D00D
+ 1962, // imageAtomicExchange_01C20D00D
+ 1964, // imageAtomicExchange_01N20D00D
+ 1966, // imageAtomicExchange_01Y20D00D
+ 1968, // imageAtomicExchange_01J00D00D
+ 1970, // imageAtomicExchange_01U00D00D
+ 1972, // imageAtomicExchange_01f00D00D
+ 1974, // imageAtomicExchange_01B20D00D
+ 1976, // imageAtomicExchange_01M20D00D
+ 1978, // imageAtomicExchange_01X20D00D
+ 1980, // imageAtomicExchange_01H20D00D
+ 1982, // imageAtomicExchange_01S20D00D
+ 1984, // imageAtomicExchange_01d20D00D
+ 1986, // imageAtomicExchange_01D00D00D
+ 1988, // imageAtomicExchange_01O00D00D
+ 1990, // imageAtomicExchange_01Z00D00D
+ 1992, // imageAtomicExchange_01E10D00D
+ 1994, // imageAtomicExchange_01P10D00D
+ 1996, // imageAtomicExchange_01a10D00D
+ 1998, // imageAtomicExchange_01I10D00D
+ 2000, // imageAtomicExchange_01T10D00D
+ 2002, // imageAtomicExchange_01e10D00D
+ 2004, // imageAtomicExchange_01F10D00D00D
+ 2006, // imageAtomicExchange_01Q10D00D00D
+ 2008, // imageAtomicExchange_01b10D00D00D
+ 2010, // imageAtomicExchange_01G20D00D00D
+ 2012, // imageAtomicExchange_01R20D00D00D
+ 2014, // imageAtomicExchange_01c20D00D00D
+ 2016, // imageAtomicExchange_00z10D00B
+ 2018, // imageAtomicExchange_01K10D00B
+ 2020, // imageAtomicExchange_01V10D00B
+ 2022, // imageAtomicExchange_01A20D00B
+ 2024, // imageAtomicExchange_01L20D00B
+ 2026, // imageAtomicExchange_01W20D00B
+ 2028, // imageAtomicExchange_01C20D00B
+ 2030, // imageAtomicExchange_01N20D00B
+ 2032, // imageAtomicExchange_01Y20D00B
+ 2034, // imageAtomicExchange_01J00D00B
+ 2036, // imageAtomicExchange_01U00D00B
+ 2038, // imageAtomicExchange_01f00D00B
+ 2040, // imageAtomicExchange_01B20D00B
+ 2042, // imageAtomicExchange_01M20D00B
+ 2044, // imageAtomicExchange_01X20D00B
+ 2046, // imageAtomicExchange_01H20D00B
+ 2048, // imageAtomicExchange_01S20D00B
+ 2050, // imageAtomicExchange_01d20D00B
+ 2052, // imageAtomicExchange_01D00D00B
+ 2054, // imageAtomicExchange_01O00D00B
+ 2056, // imageAtomicExchange_01Z00D00B
+ 2058, // imageAtomicExchange_01E10D00B
+ 2060, // imageAtomicExchange_01P10D00B
+ 2062, // imageAtomicExchange_01a10D00B
+ 2064, // imageAtomicExchange_01I10D00B
+ 2066, // imageAtomicExchange_01T10D00B
+ 2068, // imageAtomicExchange_01e10D00B
+ 2070, // imageAtomicExchange_01F10D00D00B
+ 2072, // imageAtomicExchange_01Q10D00D00B
+ 2074, // imageAtomicExchange_01b10D00D00B
+ 2076, // imageAtomicExchange_01G20D00D00B
+ 2078, // imageAtomicExchange_01R20D00D00B
+ 2080, // imageAtomicExchange_01c20D00D00B
+ 2082, // imageAtomicCompSwap_00z10D00E00E
+ 2084, // imageAtomicCompSwap_01K10D00E00E
+ 2086, // imageAtomicCompSwap_01V10D00E00E
+ 2088, // imageAtomicCompSwap_01A20D00E00E
+ 2090, // imageAtomicCompSwap_01L20D00E00E
+ 2092, // imageAtomicCompSwap_01W20D00E00E
+ 2094, // imageAtomicCompSwap_01C20D00E00E
+ 2096, // imageAtomicCompSwap_01N20D00E00E
+ 2098, // imageAtomicCompSwap_01Y20D00E00E
+ 2100, // imageAtomicCompSwap_01J00D00E00E
+ 2102, // imageAtomicCompSwap_01U00D00E00E
+ 2104, // imageAtomicCompSwap_01f00D00E00E
+ 2106, // imageAtomicCompSwap_01B20D00E00E
+ 2108, // imageAtomicCompSwap_01M20D00E00E
+ 2110, // imageAtomicCompSwap_01X20D00E00E
+ 2112, // imageAtomicCompSwap_01H20D00E00E
+ 2114, // imageAtomicCompSwap_01S20D00E00E
+ 2116, // imageAtomicCompSwap_01d20D00E00E
+ 2118, // imageAtomicCompSwap_01D00D00E00E
+ 2120, // imageAtomicCompSwap_01O00D00E00E
+ 2122, // imageAtomicCompSwap_01Z00D00E00E
+ 2124, // imageAtomicCompSwap_01E10D00E00E
+ 2126, // imageAtomicCompSwap_01P10D00E00E
+ 2128, // imageAtomicCompSwap_01a10D00E00E
+ 2130, // imageAtomicCompSwap_01I10D00E00E
+ 2132, // imageAtomicCompSwap_01T10D00E00E
+ 2134, // imageAtomicCompSwap_01e10D00E00E
+ 2136, // imageAtomicCompSwap_01F10D00D00E00E
+ 2138, // imageAtomicCompSwap_01Q10D00D00E00E
+ 2140, // imageAtomicCompSwap_01b10D00D00E00E
+ 2142, // imageAtomicCompSwap_01G20D00D00E00E
+ 2144, // imageAtomicCompSwap_01R20D00D00E00E
+ 2146, // imageAtomicCompSwap_01c20D00D00E00E
+ 2148, // imageAtomicCompSwap_00z10D00D00D
+ 2150, // imageAtomicCompSwap_01K10D00D00D
+ 2152, // imageAtomicCompSwap_01V10D00D00D
+ 2154, // imageAtomicCompSwap_01A20D00D00D
+ 2156, // imageAtomicCompSwap_01L20D00D00D
+ 2158, // imageAtomicCompSwap_01W20D00D00D
+ 2160, // imageAtomicCompSwap_01C20D00D00D
+ 2162, // imageAtomicCompSwap_01N20D00D00D
+ 2164, // imageAtomicCompSwap_01Y20D00D00D
+ 2166, // imageAtomicCompSwap_01J00D00D00D
+ 2168, // imageAtomicCompSwap_01U00D00D00D
+ 2170, // imageAtomicCompSwap_01f00D00D00D
+ 2172, // imageAtomicCompSwap_01B20D00D00D
+ 2174, // imageAtomicCompSwap_01M20D00D00D
+ 2176, // imageAtomicCompSwap_01X20D00D00D
+ 2178, // imageAtomicCompSwap_01H20D00D00D
+ 2180, // imageAtomicCompSwap_01S20D00D00D
+ 2182, // imageAtomicCompSwap_01d20D00D00D
+ 2184, // imageAtomicCompSwap_01D00D00D00D
+ 2186, // imageAtomicCompSwap_01O00D00D00D
+ 2188, // imageAtomicCompSwap_01Z00D00D00D
+ 2190, // imageAtomicCompSwap_01E10D00D00D
+ 2192, // imageAtomicCompSwap_01P10D00D00D
+ 2194, // imageAtomicCompSwap_01a10D00D00D
+ 2196, // imageAtomicCompSwap_01I10D00D00D
+ 2198, // imageAtomicCompSwap_01T10D00D00D
+ 2200, // imageAtomicCompSwap_01e10D00D00D
+ 2202, // imageAtomicCompSwap_01F10D00D00D00D
+ 2204, // imageAtomicCompSwap_01Q10D00D00D00D
+ 2206, // imageAtomicCompSwap_01b10D00D00D00D
+ 2208, // imageAtomicCompSwap_01G20D00D00D00D
+ 2210, // imageAtomicCompSwap_01R20D00D00D00D
+ 2212, // imageAtomicCompSwap_01c20D00D00D00D
+ 2214, // pixelLocalLoadANGLE_01g
+ 2215, // pixelLocalLoadANGLE_01h
+ 2216, // pixelLocalLoadANGLE_01i
+ 2217, // pixelLocalStoreANGLE_01g30B
+ 2218, // pixelLocalStoreANGLE_01h30D
+ 2219, // pixelLocalStoreANGLE_01i30E
+ 2220, // beginInvocationInterlockNV_
+ 2221, // endInvocationInterlockNV_
+ 2222, // beginFragmentShaderOrderingINTEL_
+ 2223, // beginInvocationInterlockARB_
+ 2224, // endInvocationInterlockARB_
+ 2225, // memoryBarrier_
+ 2226, // memoryBarrierAtomicCounter_
+ 2227, // memoryBarrierBuffer_
+ 2228, // memoryBarrierImage_
+ 2229, // barrier_
+ 2232, // memoryBarrierShared_
+ 2233, // groupMemoryBarrier_
+ 2234, // EmitVertex_
+ 2237, // EndPrimitive_
+ 2240, // subpassLoad_01j
+ 2241, // subpassLoad_01k
+ 2242, // subpassLoad_01l
+ 2243, // subpassLoad_01m00D
+ 2244, // subpassLoad_01n00D
+ 2245, // subpassLoad_01o00D
+ 2246, // gl_DepthRangeParameters
+ 2247, // gl_DepthRange
+ 2248, // gl_NumSamples
+ 2250, // gl_MaxVertexAttribs
+ 2251, // gl_MaxVertexUniformVectors
+ 2252, // gl_MaxVertexTextureImageUnits
+ 2253, // gl_MaxCombinedTextureImageUnits
+ 2254, // gl_MaxTextureImageUnits
+ 2255, // gl_MaxFragmentUniformVectors
+ 2256, // gl_MaxVaryingVectors
+ 2257, // gl_MaxDrawBuffers
+ 2258, // gl_MaxDualSourceDrawBuffersEXT
+ 2259, // gl_MaxVertexOutputVectors
+ 2260, // gl_MaxFragmentInputVectors
+ 2261, // gl_MinProgramTexelOffset
+ 2262, // gl_MaxProgramTexelOffset
+ 2263, // gl_MaxImageUnits
+ 2264, // gl_MaxVertexImageUniforms
+ 2265, // gl_MaxFragmentImageUniforms
+ 2266, // gl_MaxComputeImageUniforms
+ 2267, // gl_MaxCombinedImageUniforms
+ 2268, // gl_MaxCombinedShaderOutputResources
+ 2269, // gl_MaxComputeWorkGroupCount
+ 2270, // gl_MaxComputeWorkGroupSize
+ 2271, // gl_MaxComputeUniformComponents
+ 2272, // gl_MaxComputeTextureImageUnits
+ 2273, // gl_MaxComputeAtomicCounters
+ 2274, // gl_MaxComputeAtomicCounterBuffers
+ 2275, // gl_MaxVertexAtomicCounters
+ 2276, // gl_MaxFragmentAtomicCounters
+ 2277, // gl_MaxCombinedAtomicCounters
+ 2278, // gl_MaxAtomicCounterBindings
+ 2279, // gl_MaxVertexAtomicCounterBuffers
+ 2280, // gl_MaxFragmentAtomicCounterBuffers
+ 2281, // gl_MaxCombinedAtomicCounterBuffers
+ 2282, // gl_MaxAtomicCounterBufferSize
+ 2283, // gl_MaxGeometryInputComponents
+ 2286, // gl_MaxGeometryOutputComponents
+ 2289, // gl_MaxGeometryImageUniforms
+ 2292, // gl_MaxGeometryTextureImageUnits
+ 2295, // gl_MaxGeometryOutputVertices
+ 2298, // gl_MaxGeometryTotalOutputComponents
+ 2301, // gl_MaxGeometryUniformComponents
+ 2304, // gl_MaxGeometryAtomicCounters
+ 2307, // gl_MaxGeometryAtomicCounterBuffers
+ 2310, // gl_MaxTessControlInputComponents
+ 2312, // gl_MaxTessControlOutputComponents
+ 2314, // gl_MaxTessControlTextureImageUnits
+ 2316, // gl_MaxTessControlUniformComponents
+ 2318, // gl_MaxTessControlTotalOutputComponents
+ 2320, // gl_MaxTessControlImageUniforms
+ 2322, // gl_MaxTessControlAtomicCounters
+ 2324, // gl_MaxTessControlAtomicCounterBuffers
+ 2326, // gl_MaxTessPatchComponents
+ 2328, // gl_MaxPatchVertices
+ 2330, // gl_MaxTessGenLevel
+ 2332, // gl_MaxTessEvaluationInputComponents
+ 2334, // gl_MaxTessEvaluationOutputComponents
+ 2336, // gl_MaxTessEvaluationTextureImageUnits
+ 2338, // gl_MaxTessEvaluationUniformComponents
+ 2340, // gl_MaxTessEvaluationImageUniforms
+ 2342, // gl_MaxTessEvaluationAtomicCounters
+ 2344, // gl_MaxTessEvaluationAtomicCounterBuffers
+ 2346, // gl_MaxSamples
+ 2348, // gl_MaxClipDistances
+ 2349, // gl_MaxCullDistances
+ 2350, // gl_MaxCombinedClipAndCullDistances
+ 2351, // gl_FragCoord
+ 2353, // gl_FrontFacing
+ 2354, // gl_PointCoord
+ 2355, // gl_FragColor
+ 2356, // gl_FragData
+ 2357, // gl_FragDepth
+ 2358, // gl_HelperInvocation
+ 2359, // gl_SecondaryFragColorEXT
+ 2360, // gl_SecondaryFragDataEXT
+ 2361, // gl_FragDepthEXT
+ 2362, // gl_LastFragData
+ 2365, // gl_LastFragColor
+ 2366, // gl_LastFragColorARM
+ 2367, // gl_PrimitiveID
+ 2377, // gl_Layer
+ 2383, // gl_SampleID
+ 2385, // gl_SamplePosition
+ 2387, // gl_SampleMaskIn
+ 2389, // gl_SampleMask
+ 2391, // gl_CullDistance
+ 2393, // gl_ClipDistance
+ 2395, // gl_Position
+ 2403, // gl_PointSize
+ 2405, // gl_InstanceID
+ 2406, // Empty
+ 2406, // gl_VertexID
+ 2407, // Empty
+ 2407, // Empty
+ 2407, // gl_DrawID
+ 2408, // gl_BaseVertex
+ 2409, // gl_BaseInstance
+ 2410, // angle_BaseVertex
+ 2411, // angle_BaseInstance
+ 2412, // gl_NumWorkGroups
+ 2413, // gl_WorkGroupSize
+ 2414, // gl_WorkGroupID
+ 2415, // gl_LocalInvocationID
+ 2416, // gl_GlobalInvocationID
+ 2417, // gl_LocalInvocationIndex
+ 2418, // gl_PrimitiveIDIn
+ 2421, // gl_InvocationID
+ 2426, // gl_PerVertex
+ 2433, // gl_in
+ 2440, // gl_PatchVerticesIn
+ 2444, // gl_TessLevelOuter
+ 2448, // gl_TessLevelInner
+ 2452, // gl_out
+ 2456, // gl_BoundingBox
+ 2458, // gl_BoundingBoxEXT
+ 2460, // gl_BoundingBoxOES
+ 2462, // gl_TessCoord
+ 2463, // gl_ViewID_OVR
+};
+
+using Ext = TExtension;
+
+// Flat array of all unmangled name identifiers.
+constexpr UnmangledEntry unmangled[] = {
+ {"radians", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"degrees", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"sin", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"cos", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"tan", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"asin", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"acos", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"atan", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"sinh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"cosh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"tanh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"asinh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"acosh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"atanh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"pow", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"exp", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"log", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"exp2", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"log2", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"sqrt", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"inversesqrt", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"abs", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"sign", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"floor", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"trunc", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"round", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"roundEven", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"ceil", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"fract", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"mod", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"min", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"max", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"clamp", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"mix", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 450, Shader::ALL},
+ {"step", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"smoothstep", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"modf", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"isnan", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"isinf", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"floatBitsToInt", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 330,
+ Shader::ALL},
+ {"floatBitsToUint", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 330,
+ Shader::ALL},
+ {"intBitsToFloat", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 330,
+ Shader::ALL},
+ {"uintBitsToFloat", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 330,
+ Shader::ALL},
+ {"fma", std::array<TExtension, 1>{{Ext::EXT_gpu_shader5}}, Ext::UNDEFINED, 310, -1,
+ Shader::ALL},
+ {"frexp", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400, Shader::ALL},
+ {"ldexp", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400, Shader::ALL},
+ {"packSnorm2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 420,
+ Shader::ALL},
+ {"packHalf2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 420,
+ Shader::ALL},
+ {"unpackSnorm2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 420,
+ Shader::ALL},
+ {"unpackHalf2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 420,
+ Shader::ALL},
+ {"packUnorm2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 400,
+ Shader::ALL},
+ {"unpackUnorm2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 400,
+ Shader::ALL},
+ {"packUnorm4x8", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"packSnorm4x8", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"unpackUnorm4x8", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"unpackSnorm4x8", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"length", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"distance", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"dot", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"cross", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"normalize", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"faceforward", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"reflect", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"refract", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"matrixCompMult", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, -1,
+ Shader::ALL},
+ {"outerProduct", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 120,
+ Shader::ALL},
+ {"transpose", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 120,
+ Shader::ALL},
+ {"determinant", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, -1,
+ Shader::ALL},
+ {"inverse", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 140, Shader::ALL},
+ {"lessThan", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"lessThanEqual", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"greaterThan", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"greaterThanEqual", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"equal", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"notEqual", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"any", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"all", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"not", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"bitfieldExtract", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"bitfieldInsert", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"bitfieldReverse", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"bitCount", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"findLSB", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400, Shader::ALL},
+ {"findMSB", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400, Shader::ALL},
+ {"uaddCarry", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"usubBorrow", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"umulExtended", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"imulExtended", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"texture2D", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, 0,
+ Shader::FRAGMENT},
+ {"texture2DProj", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, 0,
+ Shader::FRAGMENT},
+ {"textureCube", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, 0,
+ Shader::ALL},
+ {"texture3D", std::array<TExtension, 1>{{Ext::OES_texture_3D}}, Ext::UNDEFINED, 100, -1,
+ Shader::FRAGMENT},
+ {"texture3DProj", std::array<TExtension, 1>{{Ext::OES_texture_3D}}, Ext::UNDEFINED, 100, -1,
+ Shader::FRAGMENT},
+ {"shadow2DEXT", std::array<TExtension, 1>{{Ext::EXT_shadow_samplers}}, Ext::UNDEFINED, 100, -1,
+ Shader::ALL},
+ {"shadow2DProjEXT", std::array<TExtension, 1>{{Ext::EXT_shadow_samplers}}, Ext::UNDEFINED, 100,
+ -1, Shader::ALL},
+ {"texture2DRect", std::array<TExtension, 1>{{Ext::ARB_texture_rectangle}}, Ext::UNDEFINED, 100,
+ -1, Shader::ALL},
+ {"texture2DRectProj", std::array<TExtension, 1>{{Ext::ARB_texture_rectangle}}, Ext::UNDEFINED,
+ 100, -1, Shader::ALL},
+ {"texture2DGradEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}}, Ext::UNDEFINED,
+ 100, -1, Shader::ALL},
+ {"texture2DProjGradEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}},
+ Ext::UNDEFINED, 100, -1, Shader::ALL},
+ {"textureCubeGradEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}}, Ext::UNDEFINED,
+ 100, -1, Shader::ALL},
+ {"textureVideoWEBGL", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, 0,
+ Shader::ALL},
+ {"texture3DLod", std::array<TExtension, 1>{{Ext::OES_texture_3D}}, Ext::UNDEFINED, 100, -1,
+ Shader::ALL},
+ {"texture3DProjLod", std::array<TExtension, 1>{{Ext::OES_texture_3D}}, Ext::UNDEFINED, 100, -1,
+ Shader::ALL},
+ {"texture2DLod", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, -1,
+ Shader::VERTEX},
+ {"texture2DProjLod", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, -1,
+ Shader::VERTEX},
+ {"textureCubeLod", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, -1,
+ Shader::VERTEX},
+ {"texture2DLodEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}}, Ext::UNDEFINED,
+ 100, -1, Shader::FRAGMENT},
+ {"texture2DProjLodEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}},
+ Ext::UNDEFINED, 100, -1, Shader::FRAGMENT},
+ {"textureCubeLodEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}}, Ext::UNDEFINED,
+ 100, -1, Shader::FRAGMENT},
+ {"texture", std::array<TExtension, 1>{{Ext::OES_EGL_image_external_essl3}}, Ext::UNDEFINED, 300,
+ -1, Shader::FRAGMENT},
+ {"textureProj", std::array<TExtension, 1>{{Ext::OES_EGL_image_external_essl3}}, Ext::UNDEFINED,
+ 300, -1, Shader::FRAGMENT},
+ {"textureLod",
+ std::array<TExtension, 2>{{Ext::OES_texture_cube_map_array, Ext::EXT_texture_cube_map_array}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"textureSize", std::array<TExtension, 1>{{Ext::OES_EGL_image_external_essl3}}, Ext::UNDEFINED,
+ 300, -1, Shader::ALL},
+ {"textureProjLod", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"texelFetch", std::array<TExtension, 1>{{Ext::OES_EGL_image_external_essl3}}, Ext::UNDEFINED,
+ 300, -1, Shader::ALL},
+ {"textureGrad",
+ std::array<TExtension, 2>{{Ext::OES_texture_cube_map_array, Ext::EXT_texture_cube_map_array}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"textureProjGrad", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureProjOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureLodOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureProjLodOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"texelFetchOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureGradOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureProjGradOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureGather", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"textureGatherOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"textureGatherOffsets", std::array<TExtension, 1>{{Ext::EXT_gpu_shader5}}, Ext::UNDEFINED, 310,
+ -1, Shader::ALL},
+ {"rgb_2_yuv", std::array<TExtension, 1>{{Ext::EXT_YUV_target}}, Ext::UNDEFINED, 300, -1,
+ Shader::ALL},
+ {"yuv_2_rgb", std::array<TExtension, 1>{{Ext::EXT_YUV_target}}, Ext::UNDEFINED, 300, -1,
+ Shader::ALL},
+ {"dFdx", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 0, Shader::FRAGMENT},
+ {"dFdy", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 0, Shader::FRAGMENT},
+ {"fwidth", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 0,
+ Shader::FRAGMENT},
+ {"interpolateAtCentroid",
+ std::array<TExtension, 1>{{Ext::OES_shader_multisample_interpolation}}, Ext::UNDEFINED, 300,
+ -1, Shader::FRAGMENT},
+ {"interpolateAtSample", std::array<TExtension, 1>{{Ext::OES_shader_multisample_interpolation}},
+ Ext::UNDEFINED, 300, -1, Shader::FRAGMENT},
+ {"interpolateAtOffset", std::array<TExtension, 1>{{Ext::OES_shader_multisample_interpolation}},
+ Ext::UNDEFINED, 300, -1, Shader::FRAGMENT},
+ {"atomicCounter", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 420,
+ Shader::ALL},
+ {"atomicCounterIncrement", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310,
+ 420, Shader::ALL},
+ {"atomicCounterDecrement", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310,
+ 420, Shader::ALL},
+ {"atomicAdd", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicMin", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicMax", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicAnd", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicOr", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicXor", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicExchange", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicCompSwap", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"imageSize", std::array<TExtension, 2>{{Ext::OES_texture_buffer, Ext::EXT_texture_buffer}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"imageStore", std::array<TExtension, 2>{{Ext::OES_texture_buffer, Ext::EXT_texture_buffer}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"imageLoad", std::array<TExtension, 2>{{Ext::OES_texture_buffer, Ext::EXT_texture_buffer}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"imageAtomicAdd", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicMin", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicMax", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicAnd", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicOr", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicXor", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicExchange", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"imageAtomicCompSwap", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"pixelLocalLoadANGLE", std::array<TExtension, 1>{{Ext::ANGLE_shader_pixel_local_storage}},
+ Ext::UNDEFINED, 300, -1, Shader::ALL},
+ {"pixelLocalStoreANGLE", std::array<TExtension, 1>{{Ext::ANGLE_shader_pixel_local_storage}},
+ Ext::UNDEFINED, 300, -1, Shader::ALL},
+ {"beginInvocationInterlockNV", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED,
+ kESSLInternalBackendBuiltIns, -1, Shader::ALL},
+ {"endInvocationInterlockNV", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED,
+ kESSLInternalBackendBuiltIns, -1, Shader::ALL},
+ {"beginFragmentShaderOrderingINTEL", std::array<TExtension, 1>{{Ext::UNDEFINED}},
+ Ext::UNDEFINED, kESSLInternalBackendBuiltIns, -1, Shader::ALL},
+ {"beginInvocationInterlockARB", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED,
+ kESSLInternalBackendBuiltIns, -1, Shader::ALL},
+ {"endInvocationInterlockARB", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED,
+ kESSLInternalBackendBuiltIns, -1, Shader::ALL},
+ {"memoryBarrier", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 420,
+ Shader::ALL},
+ {"memoryBarrierAtomicCounter", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310,
+ 430, Shader::ALL},
+ {"memoryBarrierBuffer", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"memoryBarrierImage", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"barrier", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 320, -1,
+ Shader::TESS_CONTROL_EXT},
+ {"memoryBarrierShared", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::COMPUTE},
+ {"groupMemoryBarrier", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::COMPUTE},
+ {"EmitVertex", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 320, -1,
+ Shader::GEOMETRY},
+ {"EndPrimitive", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 320, -1,
+ Shader::GEOMETRY},
+ {"subpassLoad", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED,
+ kESSLInternalBackendBuiltIns, 460, Shader::ALL}};
+
+} // namespace BuiltInArray
+
+void TSymbolTable::initializeBuiltInVariables(sh::GLenum shaderType,
+ ShShaderSpec spec,
+ const ShBuiltInResources &resources)
+{
+ const TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
+ TFieldList *fields_gl_DepthRangeParameters = new TFieldList();
+ fields_gl_DepthRangeParameters->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::near, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ fields_gl_DepthRangeParameters->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::far, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ fields_gl_DepthRangeParameters->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::diff, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ TStructure *gl_DepthRangeParameters = new TStructure(
+ BuiltInId::gl_DepthRangeParameters, BuiltInName::gl_DepthRangeParameters,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_DepthRangeParameters);
+ m_gl_DepthRangeParameters = gl_DepthRangeParameters;
+ TType *type_gl_DepthRange = new TType(gl_DepthRangeParameters, false);
+ type_gl_DepthRange->setQualifier(EvqUniform);
+ type_gl_DepthRange->realize();
+ m_gl_DepthRange =
+ new TVariable(BuiltInId::gl_DepthRange, BuiltInName::gl_DepthRange, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_DepthRange);
+ m_gl_MaxVertexAttribs =
+ new TVariable(BuiltInId::gl_MaxVertexAttribs, BuiltInName::gl_MaxVertexAttribs,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexAttribs);
+ static_cast<TVariable *>(m_gl_MaxVertexAttribs)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexUniformVectors = new TVariable(
+ BuiltInId::gl_MaxVertexUniformVectors, BuiltInName::gl_MaxVertexUniformVectors,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexUniformVectors);
+ static_cast<TVariable *>(m_gl_MaxVertexUniformVectors)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexTextureImageUnits = new TVariable(
+ BuiltInId::gl_MaxVertexTextureImageUnits, BuiltInName::gl_MaxVertexTextureImageUnits,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxVertexTextureImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedTextureImageUnits = new TVariable(
+ BuiltInId::gl_MaxCombinedTextureImageUnits, BuiltInName::gl_MaxCombinedTextureImageUnits,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxCombinedTextureImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTextureImageUnits =
+ new TVariable(BuiltInId::gl_MaxTextureImageUnits, BuiltInName::gl_MaxTextureImageUnits,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxTextureImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxFragmentUniformVectors = new TVariable(
+ BuiltInId::gl_MaxFragmentUniformVectors, BuiltInName::gl_MaxFragmentUniformVectors,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxFragmentUniformVectors);
+ static_cast<TVariable *>(m_gl_MaxFragmentUniformVectors)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVaryingVectors =
+ new TVariable(BuiltInId::gl_MaxVaryingVectors, BuiltInName::gl_MaxVaryingVectors,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVaryingVectors);
+ static_cast<TVariable *>(m_gl_MaxVaryingVectors)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxDrawBuffers =
+ new TVariable(BuiltInId::gl_MaxDrawBuffers, BuiltInName::gl_MaxDrawBuffers,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxDrawBuffers);
+ static_cast<TVariable *>(m_gl_MaxDrawBuffers)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxDualSourceDrawBuffersEXT = new TVariable(
+ BuiltInId::gl_MaxDualSourceDrawBuffersEXT, BuiltInName::gl_MaxDualSourceDrawBuffersEXT,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_blend_func_extended}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxDualSourceDrawBuffers);
+ static_cast<TVariable *>(m_gl_MaxDualSourceDrawBuffersEXT)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexOutputVectors =
+ new TVariable(BuiltInId::gl_MaxVertexOutputVectors, BuiltInName::gl_MaxVertexOutputVectors,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexOutputVectors);
+ static_cast<TVariable *>(m_gl_MaxVertexOutputVectors)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxFragmentInputVectors = new TVariable(
+ BuiltInId::gl_MaxFragmentInputVectors, BuiltInName::gl_MaxFragmentInputVectors,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxFragmentInputVectors);
+ static_cast<TVariable *>(m_gl_MaxFragmentInputVectors)->shareConstPointer(unionArray);
+ }
+ m_gl_MinProgramTexelOffset =
+ new TVariable(BuiltInId::gl_MinProgramTexelOffset, BuiltInName::gl_MinProgramTexelOffset,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MinProgramTexelOffset);
+ static_cast<TVariable *>(m_gl_MinProgramTexelOffset)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxProgramTexelOffset =
+ new TVariable(BuiltInId::gl_MaxProgramTexelOffset, BuiltInName::gl_MaxProgramTexelOffset,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxProgramTexelOffset);
+ static_cast<TVariable *>(m_gl_MaxProgramTexelOffset)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxImageUnits =
+ new TVariable(BuiltInId::gl_MaxImageUnits, BuiltInName::gl_MaxImageUnits,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxImageUnits);
+ static_cast<TVariable *>(m_gl_MaxImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexImageUniforms =
+ new TVariable(BuiltInId::gl_MaxVertexImageUniforms, BuiltInName::gl_MaxVertexImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxVertexImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxFragmentImageUniforms = new TVariable(
+ BuiltInId::gl_MaxFragmentImageUniforms, BuiltInName::gl_MaxFragmentImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxFragmentImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxFragmentImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeImageUniforms = new TVariable(
+ BuiltInId::gl_MaxComputeImageUniforms, BuiltInName::gl_MaxComputeImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxComputeImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxComputeImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedImageUniforms = new TVariable(
+ BuiltInId::gl_MaxCombinedImageUniforms, BuiltInName::gl_MaxCombinedImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxCombinedImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedShaderOutputResources =
+ new TVariable(BuiltInId::gl_MaxCombinedShaderOutputResources,
+ BuiltInName::gl_MaxCombinedShaderOutputResources, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedShaderOutputResources);
+ static_cast<TVariable *>(m_gl_MaxCombinedShaderOutputResources)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeWorkGroupCount = new TVariable(
+ BuiltInId::gl_MaxComputeWorkGroupCount, BuiltInName::gl_MaxComputeWorkGroupCount,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqConst, 3, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[3];
+ for (size_t index = 0u; index < 3; ++index)
+ {
+ unionArray[index].setIConst(resources.MaxComputeWorkGroupCount[index]);
+ }
+ static_cast<TVariable *>(m_gl_MaxComputeWorkGroupCount)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeWorkGroupSize = new TVariable(
+ BuiltInId::gl_MaxComputeWorkGroupSize, BuiltInName::gl_MaxComputeWorkGroupSize,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqConst, 3, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[3];
+ for (size_t index = 0u; index < 3; ++index)
+ {
+ unionArray[index].setIConst(resources.MaxComputeWorkGroupSize[index]);
+ }
+ static_cast<TVariable *>(m_gl_MaxComputeWorkGroupSize)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeUniformComponents = new TVariable(
+ BuiltInId::gl_MaxComputeUniformComponents, BuiltInName::gl_MaxComputeUniformComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxComputeUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxComputeUniformComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeTextureImageUnits = new TVariable(
+ BuiltInId::gl_MaxComputeTextureImageUnits, BuiltInName::gl_MaxComputeTextureImageUnits,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxComputeTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxComputeTextureImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeAtomicCounters = new TVariable(
+ BuiltInId::gl_MaxComputeAtomicCounters, BuiltInName::gl_MaxComputeAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxComputeAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxComputeAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxComputeAtomicCounterBuffers,
+ BuiltInName::gl_MaxComputeAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxComputeAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxComputeAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexAtomicCounters = new TVariable(
+ BuiltInId::gl_MaxVertexAtomicCounters, BuiltInName::gl_MaxVertexAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxVertexAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxFragmentAtomicCounters = new TVariable(
+ BuiltInId::gl_MaxFragmentAtomicCounters, BuiltInName::gl_MaxFragmentAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxFragmentAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxFragmentAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedAtomicCounters = new TVariable(
+ BuiltInId::gl_MaxCombinedAtomicCounters, BuiltInName::gl_MaxCombinedAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxCombinedAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxAtomicCounterBindings = new TVariable(
+ BuiltInId::gl_MaxAtomicCounterBindings, BuiltInName::gl_MaxAtomicCounterBindings,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxAtomicCounterBindings);
+ static_cast<TVariable *>(m_gl_MaxAtomicCounterBindings)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexAtomicCounterBuffers = new TVariable(
+ BuiltInId::gl_MaxVertexAtomicCounterBuffers, BuiltInName::gl_MaxVertexAtomicCounterBuffers,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxVertexAtomicCounterBuffers)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxFragmentAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxFragmentAtomicCounterBuffers,
+ BuiltInName::gl_MaxFragmentAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxFragmentAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxFragmentAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxCombinedAtomicCounterBuffers,
+ BuiltInName::gl_MaxCombinedAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxCombinedAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxAtomicCounterBufferSize = new TVariable(
+ BuiltInId::gl_MaxAtomicCounterBufferSize, BuiltInName::gl_MaxAtomicCounterBufferSize,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxAtomicCounterBufferSize);
+ static_cast<TVariable *>(m_gl_MaxAtomicCounterBufferSize)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryInputComponents =
+ new TVariable(BuiltInId::gl_MaxGeometryInputComponents,
+ BuiltInName::gl_MaxGeometryInputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryInputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryInputComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryInputComponentsES3_2 = new TVariable(
+ BuiltInId::gl_MaxGeometryInputComponentsES3_2, BuiltInName::gl_MaxGeometryInputComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryInputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryInputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryOutputComponents =
+ new TVariable(BuiltInId::gl_MaxGeometryOutputComponents,
+ BuiltInName::gl_MaxGeometryOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryOutputComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryOutputComponentsES3_2 = new TVariable(
+ BuiltInId::gl_MaxGeometryOutputComponentsES3_2, BuiltInName::gl_MaxGeometryOutputComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryOutputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryImageUniforms =
+ new TVariable(BuiltInId::gl_MaxGeometryImageUniforms,
+ BuiltInName::gl_MaxGeometryImageUniforms, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxGeometryImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryImageUniformsES3_2 = new TVariable(
+ BuiltInId::gl_MaxGeometryImageUniformsES3_2, BuiltInName::gl_MaxGeometryImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxGeometryImageUniformsES3_2)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryTextureImageUnits =
+ new TVariable(BuiltInId::gl_MaxGeometryTextureImageUnits,
+ BuiltInName::gl_MaxGeometryTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxGeometryTextureImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryTextureImageUnitsES3_2 =
+ new TVariable(BuiltInId::gl_MaxGeometryTextureImageUnitsES3_2,
+ BuiltInName::gl_MaxGeometryTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxGeometryTextureImageUnitsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryOutputVertices =
+ new TVariable(BuiltInId::gl_MaxGeometryOutputVertices,
+ BuiltInName::gl_MaxGeometryOutputVertices, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryOutputVertices);
+ static_cast<TVariable *>(m_gl_MaxGeometryOutputVertices)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryOutputVerticesES3_2 = new TVariable(
+ BuiltInId::gl_MaxGeometryOutputVerticesES3_2, BuiltInName::gl_MaxGeometryOutputVertices,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryOutputVertices);
+ static_cast<TVariable *>(m_gl_MaxGeometryOutputVerticesES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryTotalOutputComponents =
+ new TVariable(BuiltInId::gl_MaxGeometryTotalOutputComponents,
+ BuiltInName::gl_MaxGeometryTotalOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryTotalOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryTotalOutputComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryTotalOutputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxGeometryTotalOutputComponentsES3_2,
+ BuiltInName::gl_MaxGeometryTotalOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryTotalOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryTotalOutputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryUniformComponents =
+ new TVariable(BuiltInId::gl_MaxGeometryUniformComponents,
+ BuiltInName::gl_MaxGeometryUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryUniformComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryUniformComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxGeometryUniformComponentsES3_2,
+ BuiltInName::gl_MaxGeometryUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryUniformComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryAtomicCounters =
+ new TVariable(BuiltInId::gl_MaxGeometryAtomicCounters,
+ BuiltInName::gl_MaxGeometryAtomicCounters, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxGeometryAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryAtomicCountersES3_2 = new TVariable(
+ BuiltInId::gl_MaxGeometryAtomicCountersES3_2, BuiltInName::gl_MaxGeometryAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxGeometryAtomicCountersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxGeometryAtomicCounterBuffers,
+ BuiltInName::gl_MaxGeometryAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxGeometryAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryAtomicCounterBuffersES3_2 =
+ new TVariable(BuiltInId::gl_MaxGeometryAtomicCounterBuffersES3_2,
+ BuiltInName::gl_MaxGeometryAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxGeometryAtomicCounterBuffersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlInputComponents = new TVariable(
+ BuiltInId::gl_MaxTessControlInputComponents, BuiltInName::gl_MaxTessControlInputComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlInputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlInputComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlInputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlInputComponentsES3_2,
+ BuiltInName::gl_MaxTessControlInputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlInputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlInputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlOutputComponents =
+ new TVariable(BuiltInId::gl_MaxTessControlOutputComponents,
+ BuiltInName::gl_MaxTessControlOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlOutputComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlOutputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlOutputComponentsES3_2,
+ BuiltInName::gl_MaxTessControlOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlOutputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlTextureImageUnits =
+ new TVariable(BuiltInId::gl_MaxTessControlTextureImageUnits,
+ BuiltInName::gl_MaxTessControlTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxTessControlTextureImageUnits)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlTextureImageUnitsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlTextureImageUnitsES3_2,
+ BuiltInName::gl_MaxTessControlTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxTessControlTextureImageUnitsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlUniformComponents =
+ new TVariable(BuiltInId::gl_MaxTessControlUniformComponents,
+ BuiltInName::gl_MaxTessControlUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlUniformComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlUniformComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlUniformComponentsES3_2,
+ BuiltInName::gl_MaxTessControlUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlUniformComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlTotalOutputComponents =
+ new TVariable(BuiltInId::gl_MaxTessControlTotalOutputComponents,
+ BuiltInName::gl_MaxTessControlTotalOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlTotalOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlTotalOutputComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlTotalOutputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlTotalOutputComponentsES3_2,
+ BuiltInName::gl_MaxTessControlTotalOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlTotalOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlTotalOutputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlImageUniforms = new TVariable(
+ BuiltInId::gl_MaxTessControlImageUniforms, BuiltInName::gl_MaxTessControlImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxTessControlImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlImageUniformsES3_2 = new TVariable(
+ BuiltInId::gl_MaxTessControlImageUniformsES3_2, BuiltInName::gl_MaxTessControlImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxTessControlImageUniformsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlAtomicCounters = new TVariable(
+ BuiltInId::gl_MaxTessControlAtomicCounters, BuiltInName::gl_MaxTessControlAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxTessControlAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlAtomicCountersES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlAtomicCountersES3_2,
+ BuiltInName::gl_MaxTessControlAtomicCounters, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxTessControlAtomicCountersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxTessControlAtomicCounterBuffers,
+ BuiltInName::gl_MaxTessControlAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxTessControlAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlAtomicCounterBuffersES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlAtomicCounterBuffersES3_2,
+ BuiltInName::gl_MaxTessControlAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxTessControlAtomicCounterBuffersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessPatchComponents = new TVariable(
+ BuiltInId::gl_MaxTessPatchComponents, BuiltInName::gl_MaxTessPatchComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessPatchComponents);
+ static_cast<TVariable *>(m_gl_MaxTessPatchComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessPatchComponentsES3_2 = new TVariable(
+ BuiltInId::gl_MaxTessPatchComponentsES3_2, BuiltInName::gl_MaxTessPatchComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessPatchComponents);
+ static_cast<TVariable *>(m_gl_MaxTessPatchComponentsES3_2)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxPatchVertices = new TVariable(
+ BuiltInId::gl_MaxPatchVertices, BuiltInName::gl_MaxPatchVertices, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxPatchVertices);
+ static_cast<TVariable *>(m_gl_MaxPatchVertices)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxPatchVerticesES3_2 =
+ new TVariable(BuiltInId::gl_MaxPatchVerticesES3_2, BuiltInName::gl_MaxPatchVertices,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxPatchVertices);
+ static_cast<TVariable *>(m_gl_MaxPatchVerticesES3_2)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessGenLevel = new TVariable(
+ BuiltInId::gl_MaxTessGenLevel, BuiltInName::gl_MaxTessGenLevel, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessGenLevel);
+ static_cast<TVariable *>(m_gl_MaxTessGenLevel)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessGenLevelES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessGenLevelES3_2, BuiltInName::gl_MaxTessGenLevel,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessGenLevel);
+ static_cast<TVariable *>(m_gl_MaxTessGenLevelES3_2)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationInputComponents =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationInputComponents,
+ BuiltInName::gl_MaxTessEvaluationInputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationInputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationInputComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationInputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationInputComponentsES3_2,
+ BuiltInName::gl_MaxTessEvaluationInputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationInputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationInputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationOutputComponents =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationOutputComponents,
+ BuiltInName::gl_MaxTessEvaluationOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationOutputComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationOutputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationOutputComponentsES3_2,
+ BuiltInName::gl_MaxTessEvaluationOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationOutputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationTextureImageUnits =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationTextureImageUnits,
+ BuiltInName::gl_MaxTessEvaluationTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationTextureImageUnits)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationTextureImageUnitsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationTextureImageUnitsES3_2,
+ BuiltInName::gl_MaxTessEvaluationTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationTextureImageUnitsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationUniformComponents =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationUniformComponents,
+ BuiltInName::gl_MaxTessEvaluationUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationUniformComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationUniformComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationUniformComponentsES3_2,
+ BuiltInName::gl_MaxTessEvaluationUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationUniformComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationImageUniforms =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationImageUniforms,
+ BuiltInName::gl_MaxTessEvaluationImageUniforms, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationImageUniforms)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationImageUniformsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationImageUniformsES3_2,
+ BuiltInName::gl_MaxTessEvaluationImageUniforms, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationImageUniformsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationAtomicCounters =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationAtomicCounters,
+ BuiltInName::gl_MaxTessEvaluationAtomicCounters, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationAtomicCounters)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationAtomicCountersES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationAtomicCountersES3_2,
+ BuiltInName::gl_MaxTessEvaluationAtomicCounters, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationAtomicCountersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationAtomicCounterBuffers,
+ BuiltInName::gl_MaxTessEvaluationAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationAtomicCounterBuffersES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationAtomicCounterBuffersES3_2,
+ BuiltInName::gl_MaxTessEvaluationAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationAtomicCounterBuffersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxSamples =
+ new TVariable(BuiltInId::gl_MaxSamples, BuiltInName::gl_MaxSamples, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::OES_sample_variables}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxSamples);
+ static_cast<TVariable *>(m_gl_MaxSamples)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxSamplesES3_2 =
+ new TVariable(BuiltInId::gl_MaxSamplesES3_2, BuiltInName::gl_MaxSamples,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxSamples);
+ static_cast<TVariable *>(m_gl_MaxSamplesES3_2)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxClipDistancesAPPLE = new TVariable(
+ BuiltInId::gl_MaxClipDistancesAPPLE, BuiltInName::gl_MaxClipDistances, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::APPLE_clip_distance}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxClipDistances);
+ static_cast<TVariable *>(m_gl_MaxClipDistancesAPPLE)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCullDistancesEXT = new TVariable(
+ BuiltInId::gl_MaxCullDistancesEXT, BuiltInName::gl_MaxCullDistances, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_clip_cull_distance}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCullDistances);
+ static_cast<TVariable *>(m_gl_MaxCullDistancesEXT)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedClipAndCullDistancesEXT =
+ new TVariable(BuiltInId::gl_MaxCombinedClipAndCullDistancesEXT,
+ BuiltInName::gl_MaxCombinedClipAndCullDistances, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_clip_cull_distance}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedClipAndCullDistances);
+ static_cast<TVariable *>(m_gl_MaxCombinedClipAndCullDistancesEXT)
+ ->shareConstPointer(unionArray);
+ }
+ TType *type_gl_FragData = new TType(EbtFloat, EbpMedium, EvqFragData, 4);
+ if (spec != SH_WEBGL2_SPEC && spec != SH_WEBGL3_SPEC)
+ {
+ type_gl_FragData->makeArray(resources.MaxDrawBuffers);
+ }
+ else
+ {
+ type_gl_FragData->makeArray(1u);
+ }
+ type_gl_FragData->realize();
+ m_gl_FragData =
+ new TVariable(BuiltInId::gl_FragData, BuiltInName::gl_FragData, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_FragData);
+ TType *type_gl_SecondaryFragDataEXT =
+ new TType(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1);
+ type_gl_SecondaryFragDataEXT->makeArray(resources.MaxDualSourceDrawBuffers);
+ type_gl_SecondaryFragDataEXT->realize();
+ m_gl_SecondaryFragDataEXT = new TVariable(
+ BuiltInId::gl_SecondaryFragDataEXT, BuiltInName::gl_SecondaryFragDataEXT,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_blend_func_extended}},
+ type_gl_SecondaryFragDataEXT);
+ TType *type_gl_FragDepthEXT =
+ new TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1);
+ type_gl_FragDepthEXT->realize();
+ m_gl_FragDepthEXT = new TVariable(
+ BuiltInId::gl_FragDepthEXT, BuiltInName::gl_FragDepthEXT, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_frag_depth}}, type_gl_FragDepthEXT);
+ TType *type_gl_LastFragData = new TType(EbtFloat, EbpMedium, EvqLastFragData, 4, 1);
+ type_gl_LastFragData->makeArray(resources.MaxDrawBuffers);
+ type_gl_LastFragData->realize();
+ m_gl_LastFragData = new TVariable(
+ BuiltInId::gl_LastFragData, BuiltInName::gl_LastFragData, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_shader_framebuffer_fetch,
+ TExtension::EXT_shader_framebuffer_fetch_non_coherent}},
+ type_gl_LastFragData);
+ TType *type_gl_LastFragDataNV = new TType(EbtFloat, EbpMedium, EvqLastFragData, 4, 1);
+ type_gl_LastFragDataNV->makeArray(resources.MaxDrawBuffers);
+ type_gl_LastFragDataNV->realize();
+ m_gl_LastFragDataNV = new TVariable(
+ BuiltInId::gl_LastFragDataNV, BuiltInName::gl_LastFragData, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::NV_shader_framebuffer_fetch}},
+ type_gl_LastFragDataNV);
+ TType *type_gl_SampleMaskIn = new TType(EbtInt, EbpHigh, EvqSampleMaskIn, 1);
+ type_gl_SampleMaskIn->makeArray((resources.MaxSamples + 31) / 32);
+ type_gl_SampleMaskIn->realize();
+ m_gl_SampleMaskIn = new TVariable(
+ BuiltInId::gl_SampleMaskIn, BuiltInName::gl_SampleMaskIn, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::OES_sample_variables}}, type_gl_SampleMaskIn);
+ TType *type_gl_SampleMaskInES3_2 = new TType(EbtInt, EbpHigh, EvqSampleMaskIn, 1);
+ type_gl_SampleMaskInES3_2->makeArray((resources.MaxSamples + 31) / 32);
+ type_gl_SampleMaskInES3_2->realize();
+ m_gl_SampleMaskInES3_2 = new TVariable(
+ BuiltInId::gl_SampleMaskInES3_2, BuiltInName::gl_SampleMaskIn, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_SampleMaskInES3_2);
+ TType *type_gl_SampleMask = new TType(EbtInt, EbpHigh, EvqSampleMask, 1);
+ type_gl_SampleMask->makeArray((resources.MaxSamples + 31) / 32);
+ type_gl_SampleMask->realize();
+ m_gl_SampleMask = new TVariable(
+ BuiltInId::gl_SampleMask, BuiltInName::gl_SampleMask, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::OES_sample_variables}}, type_gl_SampleMask);
+ TType *type_gl_SampleMaskES3_2 = new TType(EbtInt, EbpHigh, EvqSampleMask, 1);
+ type_gl_SampleMaskES3_2->makeArray((resources.MaxSamples + 31) / 32);
+ type_gl_SampleMaskES3_2->realize();
+ m_gl_SampleMaskES3_2 = new TVariable(
+ BuiltInId::gl_SampleMaskES3_2, BuiltInName::gl_SampleMask, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_SampleMaskES3_2);
+ TType *type_gl_CullDistance = new TType(EbtFloat, EbpHigh, EvqCullDistance, 1);
+ type_gl_CullDistance->makeArray(resources.MaxCullDistances);
+ type_gl_CullDistance->realize();
+ m_gl_CullDistance = new TVariable(
+ BuiltInId::gl_CullDistance, BuiltInName::gl_CullDistance, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_clip_cull_distance}}, type_gl_CullDistance);
+ TType *type_gl_ClipDistance = new TType(EbtFloat, EbpHigh, EvqClipDistance, 1);
+ type_gl_ClipDistance->makeArray(resources.MaxClipDistances);
+ type_gl_ClipDistance->realize();
+ m_gl_ClipDistance = new TVariable(
+ BuiltInId::gl_ClipDistance, BuiltInName::gl_ClipDistance, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_clip_cull_distance}}, type_gl_ClipDistance);
+ TType *type_gl_ClipDistanceAPPLE = new TType(EbtFloat, EbpHigh, EvqClipDistance, 1);
+ type_gl_ClipDistanceAPPLE->makeArray(resources.MaxClipDistances);
+ type_gl_ClipDistanceAPPLE->realize();
+ m_gl_ClipDistanceAPPLE = new TVariable(
+ BuiltInId::gl_ClipDistanceAPPLE, BuiltInName::gl_ClipDistance, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::APPLE_clip_distance}}, type_gl_ClipDistanceAPPLE);
+ TType *type_gl_CullDistanceEXT = new TType(EbtFloat, EbpHigh, EvqCullDistance, 1);
+ type_gl_CullDistanceEXT->makeArray(resources.MaxCullDistances);
+ type_gl_CullDistanceEXT->realize();
+ m_gl_CullDistanceEXT = new TVariable(
+ BuiltInId::gl_CullDistanceEXT, BuiltInName::gl_CullDistance, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_clip_cull_distance}}, type_gl_CullDistanceEXT);
+ TFieldList *fields_gl_PerVertex = new TFieldList();
+ fields_gl_PerVertex->push_back(new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1),
+ BuiltInName::gl_Position, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertex =
+ new TInterfaceBlock(BuiltInId::gl_PerVertex, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ fields_gl_PerVertex);
+ m_gl_PerVertex = gl_PerVertex;
+ TFieldList *fields_gl_PerVertexES3_2 = new TFieldList();
+ fields_gl_PerVertexES3_2->push_back(new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1),
+ BuiltInName::gl_Position, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexES3_2);
+ m_gl_PerVertexES3_2 = gl_PerVertexES3_2;
+ TType *type_gl_in = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_in->makeArray(0u);
+ type_gl_in->realize();
+ m_gl_in = new TVariable(BuiltInId::gl_in, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ type_gl_in);
+ TType *type_gl_inES3_2 = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_inES3_2->makeArray(0u);
+ type_gl_inES3_2->realize();
+ m_gl_inES3_2 =
+ new TVariable(BuiltInId::gl_inES3_2, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_inES3_2);
+ TFieldList *fields_gl_PerVertexOutBlock = new TFieldList();
+ fields_gl_PerVertexOutBlock->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutBlock =
+ new TInterfaceBlock(BuiltInId::gl_PerVertexOutBlock, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ fields_gl_PerVertexOutBlock);
+ TFieldList *fields_gl_PerVertexOutBlockES3_2 = new TFieldList();
+ fields_gl_PerVertexOutBlockES3_2->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutBlockES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexOutBlockES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexOutBlockES3_2);
+ TType *type_gl_PositionGS = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionGS->setInterfaceBlock(gl_PerVertexOutBlock);
+ type_gl_PositionGS->realize();
+ m_gl_PositionGS =
+ new TVariable(BuiltInId::gl_PositionGS, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ type_gl_PositionGS);
+ TType *type_gl_PositionGSES3_2 = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionGSES3_2->setInterfaceBlock(gl_PerVertexOutBlockES3_2);
+ type_gl_PositionGSES3_2->realize();
+ m_gl_PositionGSES3_2 =
+ new TVariable(BuiltInId::gl_PositionGSES3_2, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_PositionGSES3_2);
+ TType *type_gl_TessLevelOuterTCS = new TType(EbtFloat, EbpHigh, EvqTessLevelOuter, 1);
+ type_gl_TessLevelOuterTCS->makeArray(4u);
+ type_gl_TessLevelOuterTCS->realize();
+ m_gl_TessLevelOuterTCS = new TVariable(
+ BuiltInId::gl_TessLevelOuterTCS, BuiltInName::gl_TessLevelOuter, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_TessLevelOuterTCS);
+ TType *type_gl_TessLevelOuterTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqTessLevelOuter, 1);
+ type_gl_TessLevelOuterTCSES3_2->makeArray(4u);
+ type_gl_TessLevelOuterTCSES3_2->realize();
+ m_gl_TessLevelOuterTCSES3_2 = new TVariable(
+ BuiltInId::gl_TessLevelOuterTCSES3_2, BuiltInName::gl_TessLevelOuter, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_TessLevelOuterTCSES3_2);
+ TType *type_gl_TessLevelInnerTCS = new TType(EbtFloat, EbpHigh, EvqTessLevelInner, 1);
+ type_gl_TessLevelInnerTCS->makeArray(2u);
+ type_gl_TessLevelInnerTCS->realize();
+ m_gl_TessLevelInnerTCS = new TVariable(
+ BuiltInId::gl_TessLevelInnerTCS, BuiltInName::gl_TessLevelInner, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_TessLevelInnerTCS);
+ TType *type_gl_TessLevelInnerTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqTessLevelInner, 1);
+ type_gl_TessLevelInnerTCSES3_2->makeArray(2u);
+ type_gl_TessLevelInnerTCSES3_2->realize();
+ m_gl_TessLevelInnerTCSES3_2 = new TVariable(
+ BuiltInId::gl_TessLevelInnerTCSES3_2, BuiltInName::gl_TessLevelInner, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_TessLevelInnerTCSES3_2);
+ TFieldList *fields_gl_PerVertexTCS = new TFieldList();
+ fields_gl_PerVertexTCS->push_back(new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1),
+ BuiltInName::gl_Position, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexTCS = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexTCS, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}}, fields_gl_PerVertexTCS);
+ m_gl_PerVertexTCS = gl_PerVertexTCS;
+ TFieldList *fields_gl_PerVertexTCSES3_2 = new TFieldList();
+ fields_gl_PerVertexTCSES3_2->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexTCSES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexTCSES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexTCSES3_2);
+ m_gl_PerVertexTCSES3_2 = gl_PerVertexTCSES3_2;
+ TType *type_gl_inTCS = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_inTCS->makeArray(resources.MaxPatchVertices);
+ type_gl_inTCS->realize();
+ m_gl_inTCS = new TVariable(BuiltInId::gl_inTCS, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_inTCS);
+ TType *type_gl_inTCSES3_2 = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_inTCSES3_2->makeArray(resources.MaxPatchVertices);
+ type_gl_inTCSES3_2->realize();
+ m_gl_inTCSES3_2 =
+ new TVariable(BuiltInId::gl_inTCSES3_2, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_inTCSES3_2);
+ TType *type_gl_outTCS = new TType(gl_PerVertex, EvqPerVertexOut, TLayoutQualifier::Create());
+ type_gl_outTCS->makeArray(resources.MaxPatchVertices);
+ type_gl_outTCS->realize();
+ m_gl_outTCS = new TVariable(BuiltInId::gl_outTCS, BuiltInName::gl_out, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_outTCS);
+ TType *type_gl_outTCSES3_2 =
+ new TType(gl_PerVertex, EvqPerVertexOut, TLayoutQualifier::Create());
+ type_gl_outTCSES3_2->makeArray(resources.MaxPatchVertices);
+ type_gl_outTCSES3_2->realize();
+ m_gl_outTCSES3_2 =
+ new TVariable(BuiltInId::gl_outTCSES3_2, BuiltInName::gl_out, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_outTCSES3_2);
+ TType *type_gl_BoundingBoxTCS = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxTCS->makeArray(2u);
+ type_gl_BoundingBoxTCS->realize();
+ m_gl_BoundingBoxTCS = new TVariable(
+ BuiltInId::gl_BoundingBoxTCS, BuiltInName::gl_BoundingBox, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}}, type_gl_BoundingBoxTCS);
+ TType *type_gl_BoundingBoxTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxTCSES3_2->makeArray(2u);
+ type_gl_BoundingBoxTCSES3_2->realize();
+ m_gl_BoundingBoxTCSES3_2 = new TVariable(
+ BuiltInId::gl_BoundingBoxTCSES3_2, BuiltInName::gl_BoundingBox, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_BoundingBoxTCSES3_2);
+ TFieldList *fields_gl_PerVertexOutTcsBlock = new TFieldList();
+ fields_gl_PerVertexOutTcsBlock->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutTcsBlock =
+ new TInterfaceBlock(BuiltInId::gl_PerVertexOutTcsBlock, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ fields_gl_PerVertexOutTcsBlock);
+ TFieldList *fields_gl_PerVertexOutTcsBlockES3_2 = new TFieldList();
+ fields_gl_PerVertexOutTcsBlockES3_2->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutTcsBlockES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexOutTcsBlockES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexOutTcsBlockES3_2);
+ TType *type_gl_PositionTCS = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionTCS->setInterfaceBlock(gl_PerVertexOutTcsBlock);
+ type_gl_PositionTCS->realize();
+ m_gl_PositionTCS = new TVariable(
+ BuiltInId::gl_PositionTCS, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}}, type_gl_PositionTCS);
+ TType *type_gl_PositionTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionTCSES3_2->setInterfaceBlock(gl_PerVertexOutTcsBlockES3_2);
+ type_gl_PositionTCSES3_2->realize();
+ m_gl_PositionTCSES3_2 = new TVariable(
+ BuiltInId::gl_PositionTCSES3_2, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_PositionTCSES3_2);
+ TType *type_gl_BoundingBoxEXTTCS = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxEXTTCS->makeArray(2u);
+ type_gl_BoundingBoxEXTTCS->realize();
+ m_gl_BoundingBoxEXTTCS = new TVariable(
+ BuiltInId::gl_BoundingBoxEXTTCS, BuiltInName::gl_BoundingBoxEXT, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_BoundingBoxEXTTCS);
+ TType *type_gl_BoundingBoxEXTTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxEXTTCSES3_2->makeArray(2u);
+ type_gl_BoundingBoxEXTTCSES3_2->realize();
+ m_gl_BoundingBoxEXTTCSES3_2 = new TVariable(
+ BuiltInId::gl_BoundingBoxEXTTCSES3_2, BuiltInName::gl_BoundingBoxEXT, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_BoundingBoxEXTTCSES3_2);
+ TType *type_gl_BoundingBoxOESTCS = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxOESTCS->makeArray(2u);
+ type_gl_BoundingBoxOESTCS->realize();
+ m_gl_BoundingBoxOESTCS = new TVariable(
+ BuiltInId::gl_BoundingBoxOESTCS, BuiltInName::gl_BoundingBoxOES, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_BoundingBoxOESTCS);
+ TType *type_gl_BoundingBoxOESTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxOESTCSES3_2->makeArray(2u);
+ type_gl_BoundingBoxOESTCSES3_2->realize();
+ m_gl_BoundingBoxOESTCSES3_2 = new TVariable(
+ BuiltInId::gl_BoundingBoxOESTCSES3_2, BuiltInName::gl_BoundingBoxOES, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_BoundingBoxOESTCSES3_2);
+ TType *type_gl_TessLevelOuterTES = new TType(EbtFloat, EbpHigh, EvqTessLevelOuter, 1);
+ type_gl_TessLevelOuterTES->makeArray(4u);
+ type_gl_TessLevelOuterTES->realize();
+ m_gl_TessLevelOuterTES = new TVariable(
+ BuiltInId::gl_TessLevelOuterTES, BuiltInName::gl_TessLevelOuter, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_TessLevelOuterTES);
+ TType *type_gl_TessLevelOuterTESES3_2 = new TType(EbtFloat, EbpHigh, EvqTessLevelOuter, 1);
+ type_gl_TessLevelOuterTESES3_2->makeArray(4u);
+ type_gl_TessLevelOuterTESES3_2->realize();
+ m_gl_TessLevelOuterTESES3_2 = new TVariable(
+ BuiltInId::gl_TessLevelOuterTESES3_2, BuiltInName::gl_TessLevelOuter, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_TessLevelOuterTESES3_2);
+ TType *type_gl_TessLevelInnerTES = new TType(EbtFloat, EbpHigh, EvqTessLevelInner, 1);
+ type_gl_TessLevelInnerTES->makeArray(2u);
+ type_gl_TessLevelInnerTES->realize();
+ m_gl_TessLevelInnerTES = new TVariable(
+ BuiltInId::gl_TessLevelInnerTES, BuiltInName::gl_TessLevelInner, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_TessLevelInnerTES);
+ TType *type_gl_TessLevelInnerTESES3_2 = new TType(EbtFloat, EbpHigh, EvqTessLevelInner, 1);
+ type_gl_TessLevelInnerTESES3_2->makeArray(2u);
+ type_gl_TessLevelInnerTESES3_2->realize();
+ m_gl_TessLevelInnerTESES3_2 = new TVariable(
+ BuiltInId::gl_TessLevelInnerTESES3_2, BuiltInName::gl_TessLevelInner, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_TessLevelInnerTESES3_2);
+ TFieldList *fields_gl_PerVertexTES = new TFieldList();
+ fields_gl_PerVertexTES->push_back(new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1),
+ BuiltInName::gl_Position, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexTES = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexTES, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}}, fields_gl_PerVertexTES);
+ m_gl_PerVertexTES = gl_PerVertexTES;
+ TFieldList *fields_gl_PerVertexTESES3_2 = new TFieldList();
+ fields_gl_PerVertexTESES3_2->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexTESES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexTESES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexTESES3_2);
+ m_gl_PerVertexTESES3_2 = gl_PerVertexTESES3_2;
+ TType *type_gl_inTES = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_inTES->makeArray(resources.MaxPatchVertices);
+ type_gl_inTES->realize();
+ m_gl_inTES = new TVariable(BuiltInId::gl_inTES, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_inTES);
+ TType *type_gl_inTESES3_2 = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_inTESES3_2->makeArray(resources.MaxPatchVertices);
+ type_gl_inTESES3_2->realize();
+ m_gl_inTESES3_2 =
+ new TVariable(BuiltInId::gl_inTESES3_2, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_inTESES3_2);
+ TType *type_gl_outTES = new TType(gl_PerVertex, EvqPerVertexOut, TLayoutQualifier::Create());
+ type_gl_outTES->makeArray(resources.MaxPatchVertices);
+ type_gl_outTES->realize();
+ m_gl_outTES = new TVariable(BuiltInId::gl_outTES, BuiltInName::gl_out, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_outTES);
+ TType *type_gl_outTESES3_2 =
+ new TType(gl_PerVertex, EvqPerVertexOut, TLayoutQualifier::Create());
+ type_gl_outTESES3_2->makeArray(resources.MaxPatchVertices);
+ type_gl_outTESES3_2->realize();
+ m_gl_outTESES3_2 =
+ new TVariable(BuiltInId::gl_outTESES3_2, BuiltInName::gl_out, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_outTESES3_2);
+ TFieldList *fields_gl_PerVertexOutTesBlock = new TFieldList();
+ fields_gl_PerVertexOutTesBlock->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutTesBlock =
+ new TInterfaceBlock(BuiltInId::gl_PerVertexOutTesBlock, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ fields_gl_PerVertexOutTesBlock);
+ TFieldList *fields_gl_PerVertexOutTesBlockES3_2 = new TFieldList();
+ fields_gl_PerVertexOutTesBlockES3_2->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutTesBlockES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexOutTesBlockES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexOutTesBlockES3_2);
+ TType *type_gl_PositionTES = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionTES->setInterfaceBlock(gl_PerVertexOutTesBlock);
+ type_gl_PositionTES->realize();
+ m_gl_PositionTES = new TVariable(
+ BuiltInId::gl_PositionTES, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}}, type_gl_PositionTES);
+ TType *type_gl_PositionTESES3_2 = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionTESES3_2->setInterfaceBlock(gl_PerVertexOutTesBlockES3_2);
+ type_gl_PositionTESES3_2->realize();
+ m_gl_PositionTESES3_2 = new TVariable(
+ BuiltInId::gl_PositionTESES3_2, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_PositionTESES3_2);
+}
+
+namespace
+{
+uint16_t GetNextRuleIndex(uint32_t nameHash)
+{
+ if (nameHash == 1645 - 1)
+ return ArraySize(BuiltInArray::kRules);
+ return BuiltInArray::kMangledOffsets[nameHash + 1];
+}
+} // namespace
+
+const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name, int shaderVersion) const
+{
+ if (name.length() > 40)
+ return nullptr;
+
+ uint32_t nameHash = name.mangledNameHash();
+ if (nameHash >= 1645)
+ return nullptr;
+
+ const char *actualName = BuiltInArray::kMangledNames[nameHash];
+ if (name != actualName)
+ return nullptr;
+
+ uint16_t startIndex = BuiltInArray::kMangledOffsets[nameHash];
+ uint16_t nextIndex = GetNextRuleIndex(nameHash);
+
+ return FindMangledBuiltIn(mShaderSpec, shaderVersion, mShaderType, mResources, *this,
+ BuiltInArray::kRules, startIndex, nextIndex);
+}
+
+bool TSymbolTable::isUnmangledBuiltInName(const ImmutableString &name,
+ int shaderVersion,
+ const TExtensionBehavior &extensions) const
+{
+ if (name.length() > 32)
+ return false;
+
+ uint32_t nameHash = name.unmangledNameHash();
+ if (nameHash >= 174)
+ return false;
+
+ return BuiltInArray::unmangled[nameHash].matches(name, mShaderSpec, shaderVersion, mShaderType,
+ extensions);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.h b/gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.h
new file mode 100644
index 0000000000..37c3c46462
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.h
@@ -0,0 +1,169 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SymbolTable_autogen.h:
+// Autogenerated member variables of TSymbolTable.
+
+#ifndef COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_
+#define COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_
+
+namespace sh
+{
+
+class TSymbolTableBase
+{
+ public:
+ TSymbolTableBase() = default;
+ TSymbol *m_gl_DepthRangeParameters = nullptr;
+ TSymbol *m_gl_DepthRange = nullptr;
+ TSymbol *m_gl_MaxVertexAttribs = nullptr;
+ TSymbol *m_gl_MaxVertexUniformVectors = nullptr;
+ TSymbol *m_gl_MaxVertexTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxCombinedTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxFragmentUniformVectors = nullptr;
+ TSymbol *m_gl_MaxVaryingVectors = nullptr;
+ TSymbol *m_gl_MaxDrawBuffers = nullptr;
+ TSymbol *m_gl_MaxDualSourceDrawBuffersEXT = nullptr;
+ TSymbol *m_gl_MaxVertexOutputVectors = nullptr;
+ TSymbol *m_gl_MaxFragmentInputVectors = nullptr;
+ TSymbol *m_gl_MinProgramTexelOffset = nullptr;
+ TSymbol *m_gl_MaxProgramTexelOffset = nullptr;
+ TSymbol *m_gl_MaxImageUnits = nullptr;
+ TSymbol *m_gl_MaxVertexImageUniforms = nullptr;
+ TSymbol *m_gl_MaxFragmentImageUniforms = nullptr;
+ TSymbol *m_gl_MaxComputeImageUniforms = nullptr;
+ TSymbol *m_gl_MaxCombinedImageUniforms = nullptr;
+ TSymbol *m_gl_MaxCombinedShaderOutputResources = nullptr;
+ TSymbol *m_gl_MaxComputeWorkGroupCount = nullptr;
+ TSymbol *m_gl_MaxComputeWorkGroupSize = nullptr;
+ TSymbol *m_gl_MaxComputeUniformComponents = nullptr;
+ TSymbol *m_gl_MaxComputeTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxComputeAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxComputeAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxVertexAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxFragmentAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxCombinedAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxAtomicCounterBindings = nullptr;
+ TSymbol *m_gl_MaxVertexAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxFragmentAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxCombinedAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxAtomicCounterBufferSize = nullptr;
+ TSymbol *m_gl_MaxGeometryInputComponents = nullptr;
+ TSymbol *m_gl_MaxGeometryInputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryOutputComponents = nullptr;
+ TSymbol *m_gl_MaxGeometryOutputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryImageUniforms = nullptr;
+ TSymbol *m_gl_MaxGeometryImageUniformsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxGeometryTextureImageUnitsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryOutputVertices = nullptr;
+ TSymbol *m_gl_MaxGeometryOutputVerticesES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryTotalOutputComponents = nullptr;
+ TSymbol *m_gl_MaxGeometryTotalOutputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryUniformComponents = nullptr;
+ TSymbol *m_gl_MaxGeometryUniformComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxGeometryAtomicCountersES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxGeometryAtomicCounterBuffersES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlInputComponents = nullptr;
+ TSymbol *m_gl_MaxTessControlInputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlOutputComponents = nullptr;
+ TSymbol *m_gl_MaxTessControlOutputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxTessControlTextureImageUnitsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlUniformComponents = nullptr;
+ TSymbol *m_gl_MaxTessControlUniformComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlTotalOutputComponents = nullptr;
+ TSymbol *m_gl_MaxTessControlTotalOutputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlImageUniforms = nullptr;
+ TSymbol *m_gl_MaxTessControlImageUniformsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxTessControlAtomicCountersES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxTessControlAtomicCounterBuffersES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessPatchComponents = nullptr;
+ TSymbol *m_gl_MaxTessPatchComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxPatchVertices = nullptr;
+ TSymbol *m_gl_MaxPatchVerticesES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessGenLevel = nullptr;
+ TSymbol *m_gl_MaxTessGenLevelES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationInputComponents = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationInputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationOutputComponents = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationOutputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationTextureImageUnitsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationUniformComponents = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationUniformComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationImageUniforms = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationImageUniformsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationAtomicCountersES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationAtomicCounterBuffersES3_2 = nullptr;
+ TSymbol *m_gl_MaxSamples = nullptr;
+ TSymbol *m_gl_MaxSamplesES3_2 = nullptr;
+ TSymbol *m_gl_MaxClipDistancesAPPLE = nullptr;
+ TSymbol *m_gl_MaxCullDistancesEXT = nullptr;
+ TSymbol *m_gl_MaxCombinedClipAndCullDistancesEXT = nullptr;
+ TSymbol *m_gl_FragData = nullptr;
+ TSymbol *m_gl_SecondaryFragDataEXT = nullptr;
+ TSymbol *m_gl_FragDepthEXT = nullptr;
+ TSymbol *m_gl_LastFragData = nullptr;
+ TSymbol *m_gl_LastFragDataNV = nullptr;
+ TSymbol *m_gl_SampleMaskIn = nullptr;
+ TSymbol *m_gl_SampleMaskInES3_2 = nullptr;
+ TSymbol *m_gl_SampleMask = nullptr;
+ TSymbol *m_gl_SampleMaskES3_2 = nullptr;
+ TSymbol *m_gl_CullDistance = nullptr;
+ TSymbol *m_gl_ClipDistance = nullptr;
+ TSymbol *m_gl_ClipDistanceAPPLE = nullptr;
+ TSymbol *m_gl_CullDistanceEXT = nullptr;
+ TSymbol *m_gl_PerVertex = nullptr;
+ TSymbol *m_gl_PerVertexES3_2 = nullptr;
+ TSymbol *m_gl_in = nullptr;
+ TSymbol *m_gl_inES3_2 = nullptr;
+ TSymbol *m_gl_PositionGS = nullptr;
+ TSymbol *m_gl_PositionGSES3_2 = nullptr;
+ TSymbol *m_gl_TessLevelOuterTCS = nullptr;
+ TSymbol *m_gl_TessLevelOuterTCSES3_2 = nullptr;
+ TSymbol *m_gl_TessLevelInnerTCS = nullptr;
+ TSymbol *m_gl_TessLevelInnerTCSES3_2 = nullptr;
+ TSymbol *m_gl_PerVertexTCS = nullptr;
+ TSymbol *m_gl_PerVertexTCSES3_2 = nullptr;
+ TSymbol *m_gl_inTCS = nullptr;
+ TSymbol *m_gl_inTCSES3_2 = nullptr;
+ TSymbol *m_gl_outTCS = nullptr;
+ TSymbol *m_gl_outTCSES3_2 = nullptr;
+ TSymbol *m_gl_BoundingBoxTCS = nullptr;
+ TSymbol *m_gl_BoundingBoxTCSES3_2 = nullptr;
+ TSymbol *m_gl_PositionTCS = nullptr;
+ TSymbol *m_gl_PositionTCSES3_2 = nullptr;
+ TSymbol *m_gl_BoundingBoxEXTTCS = nullptr;
+ TSymbol *m_gl_BoundingBoxEXTTCSES3_2 = nullptr;
+ TSymbol *m_gl_BoundingBoxOESTCS = nullptr;
+ TSymbol *m_gl_BoundingBoxOESTCSES3_2 = nullptr;
+ TSymbol *m_gl_TessLevelOuterTES = nullptr;
+ TSymbol *m_gl_TessLevelOuterTESES3_2 = nullptr;
+ TSymbol *m_gl_TessLevelInnerTES = nullptr;
+ TSymbol *m_gl_TessLevelInnerTESES3_2 = nullptr;
+ TSymbol *m_gl_PerVertexTES = nullptr;
+ TSymbol *m_gl_PerVertexTESES3_2 = nullptr;
+ TSymbol *m_gl_inTES = nullptr;
+ TSymbol *m_gl_inTESES3_2 = nullptr;
+ TSymbol *m_gl_outTES = nullptr;
+ TSymbol *m_gl_outTESES3_2 = nullptr;
+ TSymbol *m_gl_PositionTES = nullptr;
+ TSymbol *m_gl_PositionTESES3_2 = nullptr;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp b/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp
new file mode 100644
index 0000000000..2bdf08fa5f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp
@@ -0,0 +1,27 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SymbolUniqueId.cpp: Encapsulates a unique id for a symbol.
+
+#include "compiler/translator/SymbolUniqueId.h"
+
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+TSymbolUniqueId::TSymbolUniqueId(TSymbolTable *symbolTable) : mId(symbolTable->nextUniqueIdValue())
+{}
+
+TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.uniqueId().get()) {}
+
+TSymbolUniqueId &TSymbolUniqueId::operator=(const TSymbolUniqueId &) = default;
+
+bool TSymbolUniqueId::operator==(const TSymbolUniqueId &other) const
+{
+ return mId == other.mId;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h b/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h
new file mode 100644
index 0000000000..7e0312d054
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h
@@ -0,0 +1,58 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SymbolUniqueId.h: Encapsulates a unique id for a symbol.
+
+#ifndef COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
+#define COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
+
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+class TSymbolTable;
+class TSymbol;
+
+class TSymbolUniqueId
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ explicit TSymbolUniqueId(const TSymbol &symbol);
+ constexpr TSymbolUniqueId(const TSymbolUniqueId &) = default;
+ TSymbolUniqueId &operator =(const TSymbolUniqueId &);
+ bool operator==(const TSymbolUniqueId &) const;
+
+ constexpr int get() const { return mId; }
+
+ private:
+ friend class TSymbolTable;
+ explicit TSymbolUniqueId(TSymbolTable *symbolTable);
+
+ friend class BuiltInId;
+ constexpr TSymbolUniqueId(int staticId) : mId(staticId) {}
+
+ int mId;
+};
+
+enum class SymbolType : uint8_t
+{
+ BuiltIn,
+ UserDefined,
+ AngleInternal,
+ Empty // Meaning symbol without a name.
+};
+
+enum class SymbolClass : uint8_t
+{
+ Function,
+ Variable,
+ Struct,
+ InterfaceBlock
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.cpp
new file mode 100644
index 0000000000..b88e6c9ce4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.cpp
@@ -0,0 +1,1614 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// TextureFunctionHLSL: Class for writing implementations of ESSL texture functions into HLSL
+// output. Some of the implementations are straightforward and just call the HLSL equivalent of the
+// ESSL texture function, others do more work to emulate ESSL texture sampling or size query
+// behavior.
+//
+
+#include "compiler/translator/TextureFunctionHLSL.h"
+
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/UtilsHLSL.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void OutputIntTexCoordWrap(TInfoSinkBase &out,
+ const char *wrapMode,
+ const char *size,
+ const ImmutableString &texCoord,
+ const char *texCoordOffset,
+ const char *texCoordOutName)
+{
+ // GLES 3.0.4 table 3.22 specifies how the wrap modes work. We don't use the formulas verbatim
+ // but rather use equivalent formulas that map better to HLSL.
+ out << "int " << texCoordOutName << ";\n";
+ out << "float " << texCoordOutName << "Offset = " << texCoord << " + float(" << texCoordOffset
+ << ") / " << size << ";\n";
+ out << "bool " << texCoordOutName << "UseBorderColor = false;\n";
+
+ // CLAMP_TO_EDGE
+ out << "if (" << wrapMode << " == 0)\n";
+ out << "{\n";
+ out << " " << texCoordOutName << " = clamp(int(floor(" << size << " * " << texCoordOutName
+ << "Offset)), 0, int(" << size << ") - 1);\n";
+ out << "}\n";
+
+ // CLAMP_TO_BORDER
+ out << "else if (" << wrapMode << " == 3)\n";
+ out << "{\n";
+ out << " int texCoordInt = int(floor(" << size << " * " << texCoordOutName << "Offset));\n";
+ out << " " << texCoordOutName << " = clamp(texCoordInt, 0, int(" << size << ") - 1);\n";
+ out << " " << texCoordOutName << "UseBorderColor = (texCoordInt != " << texCoordOutName
+ << ");\n";
+ out << "}\n";
+
+ // MIRRORED_REPEAT
+ out << "else if (" << wrapMode << " == 2)\n";
+ out << "{\n";
+ out << " float coordWrapped = 1.0 - abs(frac(abs(" << texCoordOutName
+ << "Offset) * 0.5) * 2.0 - 1.0);\n";
+ out << " " << texCoordOutName << " = int(floor(" << size << " * coordWrapped));\n";
+ out << "}\n";
+
+ // REPEAT
+ out << "else\n";
+ out << "{\n";
+ out << " " << texCoordOutName << " = int(floor(" << size << " * frac(" << texCoordOutName
+ << "Offset)));\n";
+ out << "}\n";
+}
+
+void OutputIntTexCoordWraps(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ ImmutableString *texCoordX,
+ ImmutableString *texCoordY,
+ ImmutableString *texCoordZ)
+{
+ // Convert from normalized floating-point to integer
+ out << "int wrapS = samplerMetadata[samplerIndex].wrapModes & 0x3;\n";
+ if (textureFunction.offset)
+ {
+ OutputIntTexCoordWrap(out, "wrapS", "width", *texCoordX, "offset.x", "tix");
+ }
+ else
+ {
+ OutputIntTexCoordWrap(out, "wrapS", "width", *texCoordX, "0", "tix");
+ }
+ *texCoordX = ImmutableString("tix");
+ out << "int wrapT = (samplerMetadata[samplerIndex].wrapModes >> 2) & 0x3;\n";
+ if (textureFunction.offset)
+ {
+ OutputIntTexCoordWrap(out, "wrapT", "height", *texCoordY, "offset.y", "tiy");
+ }
+ else
+ {
+ OutputIntTexCoordWrap(out, "wrapT", "height", *texCoordY, "0", "tiy");
+ }
+ *texCoordY = ImmutableString("tiy");
+
+ bool tizAvailable = false;
+
+ if (IsSamplerArray(textureFunction.sampler))
+ {
+ *texCoordZ = ImmutableString("int(max(0, min(layers - 1, floor(0.5 + t.z))))");
+ }
+ else if (!IsSamplerCube(textureFunction.sampler) && !IsSampler2D(textureFunction.sampler))
+ {
+ out << "int wrapR = (samplerMetadata[samplerIndex].wrapModes >> 4) & 0x3;\n";
+ if (textureFunction.offset)
+ {
+ OutputIntTexCoordWrap(out, "wrapR", "depth", *texCoordZ, "offset.z", "tiz");
+ }
+ else
+ {
+ OutputIntTexCoordWrap(out, "wrapR", "depth", *texCoordZ, "0", "tiz");
+ }
+ *texCoordZ = ImmutableString("tiz");
+ tizAvailable = true;
+ }
+
+ out << "bool useBorderColor = tixUseBorderColor || tiyUseBorderColor"
+ << (tizAvailable ? " || tizUseBorderColor" : "") << ";\n";
+}
+
+void OutputHLSL4SampleFunctionPrefix(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ImmutableString &textureReference,
+ const ImmutableString &samplerReference)
+{
+ out << textureReference;
+ if (IsIntegerSampler(textureFunction.sampler) ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH)
+ {
+ out << ".Load(";
+ return;
+ }
+
+ if (IsShadowSampler(textureFunction.sampler))
+ {
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ out << ".SampleCmp(";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ case TextureFunctionHLSL::TextureFunction::GRAD:
+ out << ".SampleCmpLevelZero(";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ out << ".Sample(";
+ break;
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ out << ".SampleBias(";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ out << ".SampleLevel(";
+ break;
+ case TextureFunctionHLSL::TextureFunction::GRAD:
+ out << ".SampleGrad(";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ out << samplerReference << ", ";
+}
+
+const char *GetSamplerCoordinateTypeString(
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ int hlslCoords)
+{
+ // Gather[Red|Green|Blue|Alpha] accepts float texture coordinates on textures in integer or
+ // unsigned integer formats.
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-to-gather
+ if ((IsIntegerSampler(textureFunction.sampler) &&
+ textureFunction.method != TextureFunctionHLSL::TextureFunction::GATHER) ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH)
+ {
+ switch (hlslCoords)
+ {
+ case 1:
+ return "int";
+ case 2:
+ if (IsSampler2DMS(textureFunction.sampler))
+ {
+ return "int2";
+ }
+ else
+ {
+ return "int3";
+ }
+ case 3:
+ if (IsSampler2DMSArray(textureFunction.sampler))
+ {
+ return "int3";
+ }
+ else
+ {
+ return "int4";
+ }
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ switch (hlslCoords)
+ {
+ case 1:
+ return "float";
+ case 2:
+ return "float2";
+ case 3:
+ return "float3";
+ case 4:
+ return "float4";
+ default:
+ UNREACHABLE();
+ }
+ }
+ return "";
+}
+
+int GetHLSLCoordCount(const TextureFunctionHLSL::TextureFunction &textureFunction,
+ ShShaderOutput outputType)
+{
+ if (outputType == SH_HLSL_3_0_OUTPUT)
+ {
+ int hlslCoords = 2;
+ switch (textureFunction.sampler)
+ {
+ case EbtSamplerBuffer:
+ hlslCoords = 1;
+ break;
+ case EbtSampler2D:
+ case EbtSamplerExternalOES:
+ case EbtSampler2DMS:
+ case EbtSamplerVideoWEBGL:
+ hlslCoords = 2;
+ break;
+ case EbtSamplerCube:
+ hlslCoords = 3;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ case TextureFunctionHLSL::TextureFunction::GRAD:
+ return hlslCoords;
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ return 4;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ if (IsSamplerBuffer(textureFunction.sampler))
+ {
+ return 1;
+ }
+ else if (IsSampler3D(textureFunction.sampler) || IsSamplerArray(textureFunction.sampler) ||
+ IsSamplerCube(textureFunction.sampler))
+ {
+ return 3;
+ }
+ ASSERT(IsSampler2D(textureFunction.sampler));
+ return 2;
+ }
+ return 0;
+}
+
+void OutputTextureFunctionArgumentList(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ShShaderOutput outputType)
+{
+ if (outputType == SH_HLSL_3_0_OUTPUT)
+ {
+ switch (textureFunction.sampler)
+ {
+ case EbtSampler2D:
+ case EbtSamplerVideoWEBGL:
+ case EbtSamplerExternalOES:
+ out << "sampler2D s";
+ break;
+ case EbtSamplerCube:
+ out << "samplerCUBE s";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ out << TextureString(textureFunction.sampler) << " x, "
+ << SamplerString(textureFunction.sampler) << " s";
+ }
+ else
+ {
+ ASSERT(outputType == SH_HLSL_4_1_OUTPUT);
+ // A bug in the D3D compiler causes some nested sampling operations to fail.
+ // See http://anglebug.com/1923
+ // TODO(jmadill): Reinstate the const keyword when possible.
+ out << /*"const"*/ "uint samplerIndex";
+ }
+ }
+
+ if (textureFunction.method ==
+ TextureFunctionHLSL::TextureFunction::FETCH) // Integer coordinates
+ {
+ switch (textureFunction.coords)
+ {
+ case 1:
+ out << ", int t";
+ break;
+ case 2:
+ out << ", int2 t";
+ break;
+ case 3:
+ out << ", int3 t";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else // Floating-point coordinates (except textureSize)
+ {
+ switch (textureFunction.coords)
+ {
+ case 0:
+ break; // textureSize(gSampler2DMS sampler)
+ case 1:
+ out << ", int lod";
+ break; // textureSize()
+ case 2:
+ out << ", float2 t";
+ break;
+ case 3:
+ out << ", float3 t";
+ break;
+ case 4:
+ out << ", float4 t";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ switch (textureFunction.sampler)
+ {
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ case EbtSampler2DShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSamplerExternalOES:
+ case EbtSamplerVideoWEBGL:
+ out << ", float2 ddx, float2 ddy";
+ break;
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ case EbtSamplerCube:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCubeShadow:
+ out << ", float3 ddx, float3 ddy";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ break;
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ break; // Comes after the offset parameter
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ out << ", float lod";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ break; // Comes after the offset parameter
+ case TextureFunctionHLSL::TextureFunction::SIZE:
+ break;
+ case TextureFunctionHLSL::TextureFunction::FETCH:
+ if (IsSampler2DMS(textureFunction.sampler) ||
+ IsSampler2DMSArray(textureFunction.sampler))
+ out << ", int index";
+ else if (!IsSamplerBuffer(textureFunction.sampler))
+ out << ", int mip";
+ break;
+ case TextureFunctionHLSL::TextureFunction::GRAD:
+ break;
+ case TextureFunctionHLSL::TextureFunction::GATHER:
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GATHER &&
+ IsShadowSampler(textureFunction.sampler))
+ {
+ out << ", float refZ";
+ }
+
+ if (textureFunction.offset)
+ {
+ switch (textureFunction.sampler)
+ {
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ out << ", int3 offset";
+ break;
+ case EbtSampler2D:
+ case EbtSampler2DArray:
+ case EbtISampler2D:
+ case EbtISampler2DArray:
+ case EbtUSampler2D:
+ case EbtUSampler2DArray:
+ case EbtSampler2DShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSamplerExternalOES:
+ case EbtSamplerVideoWEBGL:
+ out << ", int2 offset";
+ break;
+ default:
+ // Offset is not supported for multisampled textures.
+ UNREACHABLE();
+ }
+ }
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
+ {
+ out << ", float bias";
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GATHER &&
+ !IsShadowSampler(textureFunction.sampler))
+ {
+ out << ", int comp = 0";
+ }
+}
+
+void GetTextureReference(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ShShaderOutput outputType,
+ ImmutableString *textureReference,
+ ImmutableString *samplerReference)
+{
+ if (outputType == SH_HLSL_4_1_OUTPUT)
+ {
+ static const ImmutableString kTexturesStr("textures");
+ static const ImmutableString kSamplersStr("samplers");
+ static const ImmutableString kSamplerIndexStr("[samplerIndex]");
+ static const ImmutableString kTextureIndexStr("[textureIndex]");
+ static const ImmutableString kSamplerArrayIndexStr("[samplerArrayIndex]");
+ ImmutableString suffix(TextureGroupSuffix(textureFunction.sampler));
+
+ if (TextureGroup(textureFunction.sampler) == HLSL_TEXTURE_2D)
+ {
+ ImmutableStringBuilder textureRefBuilder(kTexturesStr.length() + suffix.length() +
+ kSamplerIndexStr.length());
+ textureRefBuilder << kTexturesStr << suffix << kSamplerIndexStr;
+ *textureReference = textureRefBuilder;
+ ImmutableStringBuilder samplerRefBuilder(kSamplersStr.length() + suffix.length() +
+ kSamplerIndexStr.length());
+ samplerRefBuilder << kSamplersStr << suffix << kSamplerIndexStr;
+ *samplerReference = samplerRefBuilder;
+ }
+ else
+ {
+ out << " const uint textureIndex = samplerIndex - textureIndexOffset"
+ << suffix.data() << ";\n";
+ ImmutableStringBuilder textureRefBuilder(kTexturesStr.length() + suffix.length() +
+ kTextureIndexStr.length());
+ textureRefBuilder << kTexturesStr << suffix << kTextureIndexStr;
+ *textureReference = textureRefBuilder;
+
+ out << " const uint samplerArrayIndex = samplerIndex - samplerIndexOffset"
+ << suffix.data() << ";\n";
+ ImmutableStringBuilder samplerRefBuilder(kSamplersStr.length() + suffix.length() +
+ kSamplerArrayIndexStr.length());
+ samplerRefBuilder << kSamplersStr << suffix << kSamplerArrayIndexStr;
+ *samplerReference = samplerRefBuilder;
+ }
+ }
+ else
+ {
+ *textureReference = ImmutableString("x");
+ *samplerReference = ImmutableString("s");
+ }
+}
+
+void OutputTextureSizeFunctionBody(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ImmutableString &textureReference,
+ bool getDimensionsIgnoresBaseLevel)
+{
+ if (IsSampler2DMS(textureFunction.sampler))
+ {
+ out << " uint width; uint height; uint samples;\n"
+ << " " << textureReference << ".GetDimensions(width, height, samples);\n";
+ }
+ else if (IsSampler2DMSArray(textureFunction.sampler))
+ {
+ out << " uint width; uint height; uint depth; uint samples;\n"
+ << " " << textureReference << ".GetDimensions(width, height, depth, samples);\n";
+ }
+ else if (IsSamplerBuffer(textureFunction.sampler))
+ {
+ out << " uint width;\n"
+ << " " << textureReference << ".GetDimensions(width);\n";
+ }
+ else
+ {
+ if (getDimensionsIgnoresBaseLevel)
+ {
+ out << " int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n";
+ }
+ else
+ {
+ out << " int baseLevel = 0;\n";
+ }
+
+ if (IsSampler3D(textureFunction.sampler) || IsSamplerArray(textureFunction.sampler) ||
+ (IsIntegerSampler(textureFunction.sampler) && IsSamplerCube(textureFunction.sampler)))
+ {
+ // "depth" stores either the number of layers in an array texture or 3D depth
+ out << " uint width; uint height; uint depth; uint numberOfLevels;\n"
+ << " " << textureReference
+ << ".GetDimensions(baseLevel, width, height, depth, numberOfLevels);\n"
+ << " width = max(width >> lod, 1);\n"
+ << " height = max(height >> lod, 1);\n";
+
+ if (!IsSamplerArray(textureFunction.sampler))
+ {
+ out << " depth = max(depth >> lod, 1);\n";
+ }
+ }
+ else if (IsSampler2D(textureFunction.sampler) || IsSamplerCube(textureFunction.sampler))
+ {
+ out << " uint width; uint height; uint numberOfLevels;\n"
+ << " " << textureReference
+ << ".GetDimensions(baseLevel, width, height, numberOfLevels);\n"
+ << " width = max(width >> lod, 1);\n"
+ << " height = max(height >> lod, 1);\n";
+ }
+ else
+ UNREACHABLE();
+ }
+
+ const char *returnType = textureFunction.getReturnType();
+ if (strcmp(returnType, "int3") == 0)
+ {
+ out << " return int3(width, height, depth);\n";
+ }
+ else if (strcmp(returnType, "int2") == 0)
+ {
+ out << " return int2(width, height);\n";
+ }
+ else
+ {
+ out << " return int(width);\n";
+ }
+}
+
+void ProjectTextureCoordinates(const TextureFunctionHLSL::TextureFunction &textureFunction,
+ ImmutableString *texCoordX,
+ ImmutableString *texCoordY,
+ ImmutableString *texCoordZ)
+{
+ if (textureFunction.proj)
+ {
+ ImmutableString proj("");
+ switch (textureFunction.coords)
+ {
+ case 3:
+ proj = ImmutableString(" / t.z");
+ break;
+ case 4:
+ proj = ImmutableString(" / t.w");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ ImmutableStringBuilder texCoordXBuilder(texCoordX->length() + proj.length() + 2u);
+ texCoordXBuilder << '(' << *texCoordX << proj << ')';
+ *texCoordX = texCoordXBuilder;
+ ImmutableStringBuilder texCoordYBuilder(texCoordY->length() + proj.length() + 2u);
+ texCoordYBuilder << '(' << *texCoordY << proj << ')';
+ *texCoordY = texCoordYBuilder;
+ ImmutableStringBuilder texCoordZBuilder(texCoordZ->length() + proj.length() + 2u);
+ texCoordZBuilder << '(' << *texCoordZ << proj << ')';
+ *texCoordZ = texCoordZBuilder;
+ }
+}
+
+void OutputIntegerTextureSampleFunctionComputations(
+ TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ShShaderOutput outputType,
+ const ImmutableString &textureReference,
+ ImmutableString *texCoordX,
+ ImmutableString *texCoordY,
+ ImmutableString *texCoordZ,
+ bool getDimensionsIgnoresBaseLevel)
+{
+ if (!IsIntegerSampler(textureFunction.sampler))
+ {
+ return;
+ }
+
+ if (getDimensionsIgnoresBaseLevel)
+ {
+ out << " int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n";
+ }
+ else
+ {
+ out << " int baseLevel = 0;\n";
+ }
+
+ if (IsSamplerCube(textureFunction.sampler))
+ {
+ out << " float width; float height; float layers; float levels;\n";
+
+ out << " uint mip = 0;\n";
+
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel + mip, width, height, layers, levels);\n";
+
+ out << " bool xMajor = abs(t.x) >= abs(t.y) && abs(t.x) >= abs(t.z);\n";
+ out << " bool yMajor = abs(t.y) >= abs(t.z) && abs(t.y) > abs(t.x);\n";
+ out << " bool zMajor = abs(t.z) > abs(t.x) && abs(t.z) > abs(t.y);\n";
+ out << " bool negative = (xMajor && t.x < 0.0f) || (yMajor && t.y < 0.0f) || "
+ "(zMajor && t.z < 0.0f);\n";
+
+ // FACE_POSITIVE_X = 000b
+ // FACE_NEGATIVE_X = 001b
+ // FACE_POSITIVE_Y = 010b
+ // FACE_NEGATIVE_Y = 011b
+ // FACE_POSITIVE_Z = 100b
+ // FACE_NEGATIVE_Z = 101b
+ out << " int face = (int)negative + (int)yMajor * 2 + (int)zMajor * 4;\n";
+
+ out << " float u = xMajor ? -t.z : (yMajor && t.y < 0.0f ? -t.x : t.x);\n";
+ out << " float v = yMajor ? t.z : (negative ? t.y : -t.y);\n";
+ out << " float m = xMajor ? t.x : (yMajor ? t.y : t.z);\n";
+
+ out << " float3 r = any(t) ? t : float3(1, 0, 0);\n";
+ out << " t.x = (u * 0.5f / m) + 0.5f;\n";
+ out << " t.y = (v * 0.5f / m) + 0.5f;\n";
+
+ // Mip level computation.
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT)
+ {
+ // We would like to calculate tha maximum of how many texels we move in the major
+ // face's texture as we move across the screen in any direction. Namely, we want the
+ // length of the directional derivative of the function p (defined below), maximized
+ // over screen space directions. (For short: we want the norm of Dp.) For
+ // simplicity, assume that z-axis is the major axis. By symmetry, we can assume that
+ // the positive z direction is major. (The calculated value will be the same even if
+ // this is false.) Let r denote the function from screen position to cube texture
+ // coordinates. Then p can be written as p = s . P . r, where P(r) = (r.x, r.y)/r.z
+ // is the projection onto the major cube face, and s = diag(width, height)/2. (s
+ // linearly maps from the cube face into texture space, so that p(r) is in units of
+ // texels.) The derivative is
+ // Dp(r) = s |1 0 -r.x/r.z|
+ // |0 1 -r.y/r.z| |ddx(r) ddy(r)| / r.z
+ // = |dot(a, ddx(r)) dot(a, ddy(r))|
+ // |dot(b, ddx(r)) dot(b, ddy(r))| / (2 r.z)
+ // where a = w * vec3(1, 0, -r.x/r.z)
+ // b = h * vec3(0, 1, -r.y/r.z)
+ // We would like to know max(L(x)) over unit vectors x, where L(x) = |Dp(r) x|^2.
+ // Since ddx(r) and ddy(r) are unknown, the best we can do is to sample L in some
+ // directions and take the maximum across the samples.
+ //
+ // Some implementations use max(L(n1), L(n2)) where n1 = vec2(1,0) and n2 =
+ // vec2(0,1).
+ //
+ // Some implementations use max(L(n1), L(n2), L(n3), L(n4)),
+ // where n3 = (n1 + n2) / |n1 + n2| = (n1 + n2)/sqrt(2)
+ // n4 = (n1 - n2) / |n1 - n2| = (n1 - n2)/sqrt(2).
+ // In other words, two samples along the diagonal screen space directions have been
+ // added, giving a strictly better estimate of the true maximum.
+ //
+ // It turns out we can get twice the sample count very cheaply.
+ // We can use the linearity of Dp(r) to get these extra samples of L cheaply in
+ // terms of the already taken samples, L(n1) and L(n2):
+ // Denoting
+ // dpx = Dp(r)n1
+ // dpy = Dp(r)n2
+ // dpxx = dot(dpx, dpx)
+ // dpyy = dot(dpy, dpy)
+ // dpxy = dot(dpx, dpy)
+ // we obtain
+ // L(n3) = |Dp(r)n1 + Dp(r)n2|^2/2 = (dpxx + dpyy)/2 + dpxy
+ // L(n4) = |Dp(r)n1 - Dp(r)n2|^2/2 = (dpxx + dpyy)/2 - dpxy
+ // max(L(n1), L(n2), L(n3), L(n4))
+ // = max(max(L(n1), L(n2)), max(L(n3), L(n4)))
+ // = max(max(dpxx, dpyy), (dpxx + dpyy)/2 + abs(dpxy))
+ // So the extra cost is: one dot, one abs, one add, one multiply-add and one max.
+ // (All scalar.)
+ //
+ // In section 3.8.10.1, the OpenGL ES 3 specification defines the "scale factor",
+ // rho. In our terminology, this definition works out to taking sqrt(max(L(n1),
+ // L(n2))). Some implementations will use this estimate, here we use the strictly
+ // better sqrt(max(L(n1), L(n2), L(n3), L(n4))), since it's not much more expensive
+ // to calculate.
+
+ // Swap coordinates such that we can assume that the positive z-axis is major, in
+ // what follows.
+ out << " float3 ddxr = xMajor ? ddx(r).yzx : yMajor ? ddx(r).zxy : ddx(r).xyz;\n"
+ " float3 ddyr = xMajor ? ddy(r).yzx : yMajor ? ddy(r).zxy : ddy(r).xyz;\n"
+ " r = xMajor ? r.yzx : yMajor ? r.zxy : r.xyz;\n";
+
+ out << " float2 s = 0.5*float2(width, height);\n"
+ " float2 dpx = s * (ddxr.xy - ddxr.z*r.xy/r.z)/r.z;\n"
+ " float2 dpy = s * (ddyr.xy - ddyr.z*r.xy/r.z)/r.z;\n"
+ " float dpxx = dot(dpx, dpx);\n;"
+ " float dpyy = dot(dpy, dpy);\n;"
+ " float dpxy = dot(dpx, dpy);\n"
+ " float ma = max(dpxx, dpyy);\n"
+ " float mb = 0.5 * (dpxx + dpyy) + abs(dpxy);\n"
+ " float mab = max(ma, mb);\n"
+ " float lod = 0.5f * log2(mab);\n";
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ // ESSL 3.00.6 spec section 8.8: "For the cube version, the partial
+ // derivatives of P are assumed to be in the coordinate system used before
+ // texture coordinates are projected onto the appropriate cube face."
+ // ddx[0] and ddy[0] are the derivatives of t.x passed into the function
+ // ddx[1] and ddy[1] are the derivatives of t.y passed into the function
+ // ddx[2] and ddy[2] are the derivatives of t.z passed into the function
+ // Determine the derivatives of u, v and m
+ out << " float dudx = xMajor ? ddx[2] : (yMajor && t.y < 0.0f ? -ddx[0] "
+ ": ddx[0]);\n"
+ " float dudy = xMajor ? ddy[2] : (yMajor && t.y < 0.0f ? -ddy[0] "
+ ": ddy[0]);\n"
+ " float dvdx = yMajor ? ddx[2] : (negative ? ddx[1] : -ddx[1]);\n"
+ " float dvdy = yMajor ? ddy[2] : (negative ? ddy[1] : -ddy[1]);\n"
+ " float dmdx = xMajor ? ddx[0] : (yMajor ? ddx[1] : ddx[2]);\n"
+ " float dmdy = xMajor ? ddy[0] : (yMajor ? ddy[1] : ddy[2]);\n";
+ // Now determine the derivatives of the face coordinates, using the
+ // derivatives calculated above.
+ // d / dx (u(x) * 0.5 / m(x) + 0.5)
+ // = 0.5 * (m(x) * u'(x) - u(x) * m'(x)) / m(x)^2
+ out << " float dfacexdx = 0.5f * (m * dudx - u * dmdx) / (m * m);\n"
+ " float dfaceydx = 0.5f * (m * dvdx - v * dmdx) / (m * m);\n"
+ " float dfacexdy = 0.5f * (m * dudy - u * dmdy) / (m * m);\n"
+ " float dfaceydy = 0.5f * (m * dvdy - v * dmdy) / (m * m);\n"
+ " float2 sizeVec = float2(width, height);\n"
+ " float2 faceddx = float2(dfacexdx, dfaceydx) * sizeVec;\n"
+ " float2 faceddy = float2(dfacexdy, dfaceydy) * sizeVec;\n";
+ // Optimization: instead of: log2(max(length(faceddx), length(faceddy)))
+ // we compute: log2(max(length(faceddx)^2, length(faceddy)^2)) / 2
+ out << " float lengthfaceddx2 = dot(faceddx, faceddx);\n"
+ " float lengthfaceddy2 = dot(faceddy, faceddy);\n"
+ " float lod = log2(max(lengthfaceddx2, lengthfaceddy2)) * 0.5f;\n";
+ }
+ out << " mip = uint(min(max(round(lod), 0), levels - 1));\n"
+ << " " << textureReference
+ << ".GetDimensions(baseLevel + mip, width, height, layers, levels);\n";
+ }
+
+ // Convert from normalized floating-point to integer
+ static const ImmutableString kXPrefix("int(floor(width * frac(");
+ static const ImmutableString kYPrefix("int(floor(height * frac(");
+ static const ImmutableString kSuffix(")))");
+ ImmutableStringBuilder texCoordXBuilder(kXPrefix.length() + texCoordX->length() +
+ kSuffix.length());
+ texCoordXBuilder << kXPrefix << *texCoordX << kSuffix;
+ *texCoordX = texCoordXBuilder;
+ ImmutableStringBuilder texCoordYBuilder(kYPrefix.length() + texCoordX->length() +
+ kSuffix.length());
+ texCoordYBuilder << kYPrefix << *texCoordY << kSuffix;
+ *texCoordY = texCoordYBuilder;
+ *texCoordZ = ImmutableString("face");
+ }
+ else if (textureFunction.method != TextureFunctionHLSL::TextureFunction::FETCH)
+ {
+ if (IsSamplerArray(textureFunction.sampler))
+ {
+ out << " float width; float height; float layers; float levels;\n";
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
+ {
+ out << " uint mip = 0;\n";
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
+ {
+ out << " uint mip = bias;\n";
+ }
+ else
+ {
+
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel, width, height, layers, levels);\n";
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " float2 tSized = float2(t.x * width, t.y * height);\n"
+ " float dx = length(ddx(tSized));\n"
+ " float dy = length(ddy(tSized));\n"
+ " float lod = log2(max(dx, dy));\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " lod += bias;\n";
+ }
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ out << " float2 sizeVec = float2(width, height);\n"
+ " float2 sizeDdx = ddx * sizeVec;\n"
+ " float2 sizeDdy = ddy * sizeVec;\n"
+ " float lod = log2(max(dot(sizeDdx, sizeDdx), "
+ "dot(sizeDdy, sizeDdy))) * 0.5f;\n";
+ }
+
+ out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
+ }
+
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel + mip, width, height, layers, levels);\n";
+ }
+ else if (IsSampler2D(textureFunction.sampler))
+ {
+ out << " float width; float height; float levels;\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
+ {
+ out << " uint mip = 0;\n";
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
+ {
+ out << " uint mip = bias;\n";
+ }
+ else
+ {
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel, width, height, levels);\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " float2 tSized = float2(t.x * width, t.y * height);\n"
+ " float dx = length(ddx(tSized));\n"
+ " float dy = length(ddy(tSized));\n"
+ " float lod = log2(max(dx, dy));\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " lod += bias;\n";
+ }
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ out << " float2 sizeVec = float2(width, height);\n"
+ " float2 sizeDdx = ddx * sizeVec;\n"
+ " float2 sizeDdy = ddy * sizeVec;\n"
+ " float lod = log2(max(dot(sizeDdx, sizeDdx), "
+ "dot(sizeDdy, sizeDdy))) * 0.5f;\n";
+ }
+
+ out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
+ }
+
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel + mip, width, height, levels);\n";
+ }
+ else if (IsSampler3D(textureFunction.sampler))
+ {
+ out << " float width; float height; float depth; float levels;\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
+ {
+ out << " uint mip = 0;\n";
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
+ {
+ out << " uint mip = bias;\n";
+ }
+ else
+ {
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel, width, height, depth, levels);\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " float3 tSized = float3(t.x * width, t.y * height, t.z * depth);\n"
+ " float dx = length(ddx(tSized));\n"
+ " float dy = length(ddy(tSized));\n"
+ " float lod = log2(max(dx, dy));\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " lod += bias;\n";
+ }
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ out << " float3 sizeVec = float3(width, height, depth);\n"
+ " float3 sizeDdx = ddx * sizeVec;\n"
+ " float3 sizeDdy = ddy * sizeVec;\n"
+ " float lod = log2(max(dot(sizeDdx, sizeDdx), dot(sizeDdy, "
+ "sizeDdy))) * 0.5f;\n";
+ }
+
+ out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
+ }
+
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel + mip, width, height, depth, levels);\n";
+ }
+ else
+ UNREACHABLE();
+
+ OutputIntTexCoordWraps(out, textureFunction, texCoordX, texCoordY, texCoordZ);
+ }
+}
+
+void OutputTextureGatherFunctionBody(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ ShShaderOutput outputType,
+ const ImmutableString &textureReference,
+ const ImmutableString &samplerReference,
+ const ImmutableString &texCoordX,
+ const ImmutableString &texCoordY,
+ const ImmutableString &texCoordZ)
+{
+ const int hlslCoords = GetHLSLCoordCount(textureFunction, outputType);
+ ImmutableString samplerCoordTypeString(
+ GetSamplerCoordinateTypeString(textureFunction, hlslCoords));
+ ImmutableStringBuilder samplerCoordBuilder(
+ samplerCoordTypeString.length() + strlen("(") + texCoordX.length() + strlen(", ") +
+ texCoordY.length() + strlen(", ") + texCoordZ.length() + strlen(")"));
+
+ samplerCoordBuilder << samplerCoordTypeString << "(" << texCoordX << ", " << texCoordY;
+ if (hlslCoords >= 3)
+ {
+ if (textureFunction.coords < 3)
+ {
+ samplerCoordBuilder << ", 0";
+ }
+ else
+ {
+ samplerCoordBuilder << ", " << texCoordZ;
+ }
+ }
+ samplerCoordBuilder << ")";
+
+ ImmutableString samplerCoordString(samplerCoordBuilder);
+
+ if (IsShadowSampler(textureFunction.sampler))
+ {
+ out << "return " << textureReference << ".GatherCmp(" << samplerReference << ", "
+ << samplerCoordString << ", refZ";
+ if (textureFunction.offset)
+ {
+ out << ", offset";
+ }
+ out << ");\n";
+ return;
+ }
+
+ constexpr std::array<const char *, 4> kHLSLGatherFunctions = {
+ {"GatherRed", "GatherGreen", "GatherBlue", "GatherAlpha"}};
+
+ out << " switch(comp)\n"
+ " {\n";
+ for (size_t component = 0; component < kHLSLGatherFunctions.size(); ++component)
+ {
+ out << " case " << component << ":\n"
+ << " return " << textureReference << "." << kHLSLGatherFunctions[component]
+ << "(" << samplerReference << ", " << samplerCoordString;
+ if (textureFunction.offset)
+ {
+ out << ", offset";
+ }
+ out << ");\n";
+ }
+
+ out << " default:\n"
+ " return float4(0.0, 0.0, 0.0, 1.0);\n"
+ " }\n";
+}
+
+void OutputTextureSampleFunctionReturnStatement(
+ TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ShShaderOutput outputType,
+ const ImmutableString &textureReference,
+ const ImmutableString &samplerReference,
+ const ImmutableString &texCoordX,
+ const ImmutableString &texCoordY,
+ const ImmutableString &texCoordZ)
+{
+ out << " return ";
+
+ if (IsIntegerSampler(textureFunction.sampler) && !IsSamplerCube(textureFunction.sampler) &&
+ textureFunction.method != TextureFunctionHLSL::TextureFunction::FETCH)
+ {
+ out << " useBorderColor ? ";
+ if (IsIntegerSamplerUnsigned(textureFunction.sampler))
+ {
+ out << "asuint";
+ }
+ out << "(samplerMetadata[samplerIndex].intBorderColor) : ";
+ }
+
+ // HLSL intrinsic
+ if (outputType == SH_HLSL_3_0_OUTPUT)
+ {
+ switch (textureFunction.sampler)
+ {
+ case EbtSampler2D:
+ case EbtSamplerVideoWEBGL:
+ case EbtSamplerExternalOES:
+ out << "tex2D";
+ break;
+ case EbtSamplerCube:
+ out << "texCUBE";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ out << "(" << samplerReference << ", ";
+ break;
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ out << "bias(" << samplerReference << ", ";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ out << "lod(" << samplerReference << ", ";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ out << "lod(" << samplerReference << ", ";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ out << "lod(" << samplerReference << ", ";
+ break;
+ case TextureFunctionHLSL::TextureFunction::GRAD:
+ out << "grad(" << samplerReference << ", ";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else if (outputType == SH_HLSL_4_1_OUTPUT || outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ OutputHLSL4SampleFunctionPrefix(out, textureFunction, textureReference, samplerReference);
+ }
+ else
+ UNREACHABLE();
+
+ const int hlslCoords = GetHLSLCoordCount(textureFunction, outputType);
+ out << GetSamplerCoordinateTypeString(textureFunction, hlslCoords);
+
+ if (hlslCoords >= 2)
+ {
+ out << "(" << texCoordX << ", " << texCoordY;
+ }
+ else if (hlslCoords == 1)
+ {
+ std::string varName(texCoordX.data());
+ if (size_t pos = varName.find_last_of('.') != std::string::npos)
+ {
+ varName = varName.substr(0, pos);
+ }
+ out << "(" << varName;
+ }
+ else
+ {
+ out << "(";
+ }
+
+ if (outputType == SH_HLSL_3_0_OUTPUT)
+ {
+ if (hlslCoords >= 3)
+ {
+ if (textureFunction.coords < 3)
+ {
+ out << ", 0";
+ }
+ else
+ {
+ out << ", " << texCoordZ;
+ }
+ }
+
+ if (hlslCoords == 4)
+ {
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ out << ", bias";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ out << ", lod";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ out << ", 0";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ out << ", bias";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ out << ")";
+ }
+ else if (outputType == SH_HLSL_4_1_OUTPUT || outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ if (hlslCoords >= 3)
+ {
+ ASSERT(!IsIntegerSampler(textureFunction.sampler) ||
+ !IsSamplerCube(textureFunction.sampler) || texCoordZ == "face");
+ out << ", " << texCoordZ;
+ }
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ if (IsIntegerSampler(textureFunction.sampler))
+ {
+ out << ", mip)";
+ }
+ else if (IsShadowSampler(textureFunction.sampler))
+ {
+ // Compare value
+ if (textureFunction.proj)
+ {
+ // According to ESSL 3.00.4 sec 8.8 p95 on textureProj:
+ // The resulting third component of P' in the shadow forms is used as
+ // Dref
+ out << "), " << texCoordZ;
+ }
+ else
+ {
+ switch (textureFunction.coords)
+ {
+ case 3:
+ out << "), t.z";
+ break;
+ case 4:
+ out << "), t.w";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+ else
+ {
+ out << "), ddx, ddy";
+ }
+ }
+ else if (IsIntegerSampler(textureFunction.sampler) ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH)
+ {
+ if (IsSampler2DMS(textureFunction.sampler) ||
+ IsSampler2DMSArray(textureFunction.sampler))
+ out << "), index";
+ else if (IsSamplerBuffer(textureFunction.sampler))
+ out << ")";
+ else
+ out << ", mip)";
+ }
+ else if (IsShadowSampler(textureFunction.sampler))
+ {
+ // Compare value
+ if (textureFunction.proj)
+ {
+ // According to ESSL 3.00.4 sec 8.8 p95 on textureProj:
+ // The resulting third component of P' in the shadow forms is used as Dref
+ out << "), " << texCoordZ;
+ }
+ else
+ {
+ switch (textureFunction.coords)
+ {
+ case 3:
+ out << "), t.z";
+ break;
+ case 4:
+ out << "), t.w";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+ else
+ {
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ out << ")";
+ break;
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ out << "), bias";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ out << "), lod";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ out << "), 0";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ out << "), bias";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ if (textureFunction.offset &&
+ (!IsIntegerSampler(textureFunction.sampler) ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH))
+ {
+ out << ", offset";
+ }
+ }
+ else
+ UNREACHABLE();
+
+ out << ");\n"; // Close the sample function call and return statement
+}
+
+} // Anonymous namespace
+
+ImmutableString TextureFunctionHLSL::TextureFunction::name() const
+{
+ static const ImmutableString kGlTextureName("gl_texture");
+
+ ImmutableString suffix(TextureTypeSuffix(this->sampler));
+
+ ImmutableStringBuilder name(kGlTextureName.length() + suffix.length() + 4u + 6u + 5u);
+
+ name << kGlTextureName;
+
+ // We need to include full the sampler type in the function name to make the signature unique
+ // on D3D11, where samplers are passed to texture functions as indices.
+ name << suffix;
+
+ if (proj)
+ {
+ name << "Proj";
+ }
+
+ if (offset)
+ {
+ name << "Offset";
+ }
+
+ switch (method)
+ {
+ case IMPLICIT:
+ break;
+ case BIAS:
+ break; // Extra parameter makes the signature unique
+ case LOD:
+ name << "Lod";
+ break;
+ case LOD0:
+ name << "Lod0";
+ break;
+ case LOD0BIAS:
+ name << "Lod0";
+ break; // Extra parameter makes the signature unique
+ case SIZE:
+ name << "Size";
+ break;
+ case FETCH:
+ name << "Fetch";
+ break;
+ case GRAD:
+ name << "Grad";
+ break;
+ case GATHER:
+ name << "Gather";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return name;
+}
+
+const char *TextureFunctionHLSL::TextureFunction::getReturnType() const
+{
+ if (method == TextureFunction::SIZE)
+ {
+ switch (sampler)
+ {
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DShadow:
+ case EbtSamplerCube:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCubeShadow:
+ case EbtSamplerExternalOES:
+ case EbtSampler2DMS:
+ case EbtISampler2DMS:
+ case EbtUSampler2DMS:
+ case EbtSamplerVideoWEBGL:
+ return "int2";
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ case EbtSampler2DMSArray:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DArrayShadow:
+ return "int3";
+ case EbtISamplerBuffer:
+ case EbtUSamplerBuffer:
+ case EbtSamplerBuffer:
+ return "int";
+ default:
+ UNREACHABLE();
+ }
+ }
+ else // Sampling function
+ {
+ switch (sampler)
+ {
+ case EbtSampler2D:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtSampler3D:
+ case EbtSamplerCube:
+ case EbtSampler2DArray:
+ case EbtSamplerExternalOES:
+ case EbtSamplerVideoWEBGL:
+ case EbtSamplerBuffer:
+ return "float4";
+ case EbtISampler2D:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtISampler3D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISamplerBuffer:
+ return "int4";
+ case EbtUSampler2D:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtUSampler3D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSamplerBuffer:
+ return "uint4";
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler2DArrayShadow:
+ if (method == TextureFunctionHLSL::TextureFunction::GATHER)
+ {
+ return "float4";
+ }
+ else
+ {
+ return "float";
+ }
+ default:
+ UNREACHABLE();
+ }
+ }
+ return "";
+}
+
+bool TextureFunctionHLSL::TextureFunction::operator<(const TextureFunction &rhs) const
+{
+ return std::tie(sampler, coords, proj, offset, method) <
+ std::tie(rhs.sampler, rhs.coords, rhs.proj, rhs.offset, rhs.method);
+}
+
+ImmutableString TextureFunctionHLSL::useTextureFunction(const ImmutableString &name,
+ TBasicType samplerType,
+ int coords,
+ size_t argumentCount,
+ bool lod0,
+ sh::GLenum shaderType)
+{
+ TextureFunction textureFunction;
+ textureFunction.sampler = samplerType;
+ textureFunction.coords = coords;
+ textureFunction.method = TextureFunction::IMPLICIT;
+ textureFunction.proj = false;
+ textureFunction.offset = false;
+
+ if (name == "texture2D" || name == "textureCube" || name == "texture")
+ {
+ textureFunction.method = TextureFunction::IMPLICIT;
+ }
+ else if (name == "texture2DProj" || name == "textureProj")
+ {
+ textureFunction.method = TextureFunction::IMPLICIT;
+ textureFunction.proj = true;
+ }
+ else if (name == "texture2DLod" || name == "textureCubeLod" || name == "textureLod" ||
+ name == "texture2DLodEXT" || name == "textureCubeLodEXT")
+ {
+ textureFunction.method = TextureFunction::LOD;
+ }
+ else if (name == "texture2DProjLod" || name == "textureProjLod" ||
+ name == "texture2DProjLodEXT")
+ {
+ textureFunction.method = TextureFunction::LOD;
+ textureFunction.proj = true;
+ }
+ else if (name == "textureSize")
+ {
+ textureFunction.method = TextureFunction::SIZE;
+ }
+ else if (name == "textureOffset")
+ {
+ textureFunction.method = TextureFunction::IMPLICIT;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureProjOffset")
+ {
+ textureFunction.method = TextureFunction::IMPLICIT;
+ textureFunction.offset = true;
+ textureFunction.proj = true;
+ }
+ else if (name == "textureLodOffset")
+ {
+ textureFunction.method = TextureFunction::LOD;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureProjLodOffset")
+ {
+ textureFunction.method = TextureFunction::LOD;
+ textureFunction.proj = true;
+ textureFunction.offset = true;
+ }
+ else if (name == "texelFetch")
+ {
+ textureFunction.method = TextureFunction::FETCH;
+ }
+ else if (name == "texelFetchOffset")
+ {
+ textureFunction.method = TextureFunction::FETCH;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureGrad" || name == "texture2DGradEXT")
+ {
+ textureFunction.method = TextureFunction::GRAD;
+ }
+ else if (name == "textureGradOffset")
+ {
+ textureFunction.method = TextureFunction::GRAD;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureProjGrad" || name == "texture2DProjGradEXT" ||
+ name == "textureCubeGradEXT")
+ {
+ textureFunction.method = TextureFunction::GRAD;
+ textureFunction.proj = true;
+ }
+ else if (name == "textureProjGradOffset")
+ {
+ textureFunction.method = TextureFunction::GRAD;
+ textureFunction.proj = true;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureGather")
+ {
+ textureFunction.method = TextureFunction::GATHER;
+ }
+ else if (name == "textureGatherOffset")
+ {
+ textureFunction.method = TextureFunction::GATHER;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureVideoWEBGL")
+ {
+ textureFunction.method = TextureFunction::IMPLICIT;
+ }
+ else
+ UNREACHABLE();
+
+ if (textureFunction.method ==
+ TextureFunction::IMPLICIT) // Could require lod 0 or have a bias argument
+ {
+ size_t mandatoryArgumentCount = 2; // All functions have sampler and coordinate arguments
+
+ if (textureFunction.offset)
+ {
+ mandatoryArgumentCount++;
+ }
+
+ bool bias = (argumentCount > mandatoryArgumentCount); // Bias argument is optional
+
+ if (lod0 || shaderType == GL_VERTEX_SHADER || shaderType == GL_COMPUTE_SHADER)
+ {
+ if (bias)
+ {
+ textureFunction.method = TextureFunction::LOD0BIAS;
+ }
+ else
+ {
+ textureFunction.method = TextureFunction::LOD0;
+ }
+ }
+ else if (bias)
+ {
+ textureFunction.method = TextureFunction::BIAS;
+ }
+ }
+
+ mUsesTexture.insert(textureFunction);
+ return textureFunction.name();
+}
+
+void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out,
+ const ShShaderOutput outputType,
+ bool getDimensionsIgnoresBaseLevel)
+{
+ for (const TextureFunction &textureFunction : mUsesTexture)
+ {
+ // Function header
+ out << textureFunction.getReturnType() << " " << textureFunction.name() << "(";
+
+ OutputTextureFunctionArgumentList(out, textureFunction, outputType);
+
+ out << ")\n"
+ "{\n";
+
+ // In some cases we use a variable to store the texture/sampler objects, but to work around
+ // a D3D11 compiler bug related to discard inside a loop that is conditional on texture
+ // sampling we need to call the function directly on references to the texture and sampler
+ // arrays. The bug was found using dEQP-GLES3.functional.shaders.discard*loop_texture*
+ // tests.
+ ImmutableString textureReference("");
+ ImmutableString samplerReference("");
+ GetTextureReference(out, textureFunction, outputType, &textureReference, &samplerReference);
+
+ if (textureFunction.method == TextureFunction::SIZE)
+ {
+ OutputTextureSizeFunctionBody(out, textureFunction, textureReference,
+ getDimensionsIgnoresBaseLevel);
+ }
+ else
+ {
+ ImmutableString texCoordX("t.x");
+ ImmutableString texCoordY("t.y");
+ ImmutableString texCoordZ("t.z");
+ if (textureFunction.method == TextureFunction::GATHER)
+ {
+ OutputTextureGatherFunctionBody(out, textureFunction, outputType, textureReference,
+ samplerReference, texCoordX, texCoordY, texCoordZ);
+ }
+ else
+ {
+ ProjectTextureCoordinates(textureFunction, &texCoordX, &texCoordY, &texCoordZ);
+ OutputIntegerTextureSampleFunctionComputations(
+ out, textureFunction, outputType, textureReference, &texCoordX, &texCoordY,
+ &texCoordZ, getDimensionsIgnoresBaseLevel);
+ OutputTextureSampleFunctionReturnStatement(out, textureFunction, outputType,
+ textureReference, samplerReference,
+ texCoordX, texCoordY, texCoordZ);
+ }
+ }
+
+ out << "}\n"
+ "\n";
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.h b/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.h
new file mode 100644
index 0000000000..6e81ad00c6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.h
@@ -0,0 +1,77 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// TextureFunctionHLSL: Class for writing implementations of ESSL texture functions into HLSL
+// output. Some of the implementations are straightforward and just call the HLSL equivalent of the
+// ESSL texture function, others do more work to emulate ESSL texture sampling or size query
+// behavior.
+//
+
+#ifndef COMPILER_TRANSLATOR_TEXTUREFUNCTIONHLSL_H_
+#define COMPILER_TRANSLATOR_TEXTUREFUNCTIONHLSL_H_
+
+#include <set>
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/InfoSink.h"
+
+namespace sh
+{
+
+class TextureFunctionHLSL final : angle::NonCopyable
+{
+ public:
+ struct TextureFunction
+ {
+ // See ESSL 3.00.6 section 8.8 for reference about what the different methods below do.
+ enum Method
+ {
+ IMPLICIT, // Mipmap LOD determined implicitly (standard lookup)
+ BIAS,
+ LOD,
+ LOD0,
+ LOD0BIAS,
+ SIZE, // textureSize()
+ FETCH,
+ GRAD,
+ GATHER
+ };
+
+ ImmutableString name() const;
+
+ bool operator<(const TextureFunction &rhs) const;
+
+ const char *getReturnType() const;
+
+ TBasicType sampler;
+ int coords;
+ bool proj;
+ bool offset;
+ Method method;
+ };
+
+ // Returns the name of the texture function implementation to call.
+ // The name that's passed in is the name of the GLSL texture function that it should implement.
+ ImmutableString useTextureFunction(const ImmutableString &name,
+ TBasicType samplerType,
+ int coords,
+ size_t argumentCount,
+ bool lod0,
+ sh::GLenum shaderType);
+
+ void textureFunctionHeader(TInfoSinkBase &out,
+ const ShShaderOutput outputType,
+ bool getDimensionsIgnoresBaseLevel);
+
+ private:
+ typedef std::set<TextureFunction> TextureFunctionSet;
+ TextureFunctionSet mUsesTexture;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TEXTUREFUNCTIONHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp b/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp
new file mode 100644
index 0000000000..5179b8c9b3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp
@@ -0,0 +1,219 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/TranslatorESSL.h"
+
+#include "angle_gl.h"
+#include "common/utilities.h"
+#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
+#include "compiler/translator/OutputESSL.h"
+#include "compiler/translator/tree_ops/RecordConstantPrecision.h"
+
+namespace sh
+{
+
+TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
+ : TCompiler(type, spec, SH_ESSL_OUTPUT)
+{}
+
+void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
+ const ShCompileOptions &compileOptions)
+{
+ if (compileOptions.emulateAtan2FloatFunction)
+ {
+ InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(emu);
+ }
+}
+
+bool TranslatorESSL::translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics * /*perfDiagnostics*/)
+{
+ TInfoSinkBase &sink = getInfoSink().obj;
+
+ int shaderVer = getShaderVersion(); // Frontend shader version.
+ if (hasPixelLocalStorageUniforms() &&
+ ShPixelLocalStorageTypeUsesImages(compileOptions.pls.type))
+ {
+ // The backend translator emits shader image code. Use a minimum version of 310.
+ shaderVer = std::max(shaderVer, 310);
+ }
+ if (shaderVer > 100)
+ {
+ sink << "#version " << shaderVer << " es\n";
+ }
+
+ // Write built-in extension behaviors.
+ writeExtensionBehavior(compileOptions);
+
+ // Write pragmas after extensions because some drivers consider pragmas
+ // like non-preprocessor tokens.
+ WritePragma(sink, compileOptions, getPragma());
+
+ if (!RecordConstantPrecision(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+
+ // Write emulated built-in functions if needed.
+ if (!getBuiltInFunctionEmulator().isOutputEmpty())
+ {
+ sink << "// BEGIN: Generated code for built-in function emulation\n\n";
+ if (getShaderType() == GL_FRAGMENT_SHADER)
+ {
+ sink << "#if defined(GL_FRAGMENT_PRECISION_HIGH)\n"
+ << "#define emu_precision highp\n"
+ << "#else\n"
+ << "#define emu_precision mediump\n"
+ << "#endif\n\n";
+ }
+ else
+ {
+ sink << "#define emu_precision highp\n";
+ }
+
+ getBuiltInFunctionEmulator().outputEmulatedFunctions(sink);
+ sink << "// END: Generated code for built-in function emulation\n\n";
+ }
+
+ if (getShaderType() == GL_FRAGMENT_SHADER)
+ {
+ EmitEarlyFragmentTestsGLSL(*this, sink);
+ }
+
+ if (getShaderType() == GL_COMPUTE_SHADER)
+ {
+ EmitWorkGroupSizeGLSL(*this, sink);
+ }
+
+ if (getShaderType() == GL_GEOMETRY_SHADER_EXT)
+ {
+ WriteGeometryShaderLayoutQualifiers(
+ sink, getGeometryShaderInputPrimitiveType(), getGeometryShaderInvocations(),
+ getGeometryShaderOutputPrimitiveType(), getGeometryShaderMaxVertices());
+ }
+
+ // Write translated shader.
+ TOutputESSL outputESSL(this, sink, compileOptions);
+
+ root->traverse(&outputESSL);
+
+ return true;
+}
+
+bool TranslatorESSL::shouldFlattenPragmaStdglInvariantAll()
+{
+ // If following the spec to the letter, we should not flatten this pragma.
+ // However, the spec's wording means that the pragma applies only to outputs.
+ // This contradicts the spirit of using the pragma,
+ // because if the pragma is used in a vertex shader,
+ // the only way to be able to link it to a fragment shader
+ // is to manually qualify each of fragment shader's inputs as invariant.
+ // Which defeats the purpose of this pragma - temporarily make all varyings
+ // invariant for debugging.
+ // Thus, we should be non-conformant to spec's letter here and flatten.
+ return true;
+}
+
+void TranslatorESSL::writeExtensionBehavior(const ShCompileOptions &compileOptions)
+{
+ TInfoSinkBase &sink = getInfoSink().obj;
+ const TExtensionBehavior &extBehavior = getExtensionBehavior();
+ for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end();
+ ++iter)
+ {
+ if (iter->second != EBhUndefined)
+ {
+ const bool isMultiview = (iter->first == TExtension::OVR_multiview) ||
+ (iter->first == TExtension::OVR_multiview2);
+ if (getResources().NV_shader_framebuffer_fetch &&
+ iter->first == TExtension::EXT_shader_framebuffer_fetch)
+ {
+ sink << "#extension GL_NV_shader_framebuffer_fetch : "
+ << GetBehaviorString(iter->second) << "\n";
+ }
+ else if (getResources().NV_draw_buffers && iter->first == TExtension::EXT_draw_buffers)
+ {
+ sink << "#extension GL_NV_draw_buffers : " << GetBehaviorString(iter->second)
+ << "\n";
+ }
+ else if (isMultiview)
+ {
+ // Only either OVR_multiview OR OVR_multiview2 should be emitted.
+ if ((iter->first != TExtension::OVR_multiview) ||
+ !IsExtensionEnabled(extBehavior, TExtension::OVR_multiview2))
+ {
+ EmitMultiviewGLSL(*this, compileOptions, iter->first, iter->second, sink);
+ }
+ }
+ else if (iter->first == TExtension::EXT_geometry_shader ||
+ iter->first == TExtension::OES_geometry_shader)
+ {
+ sink << "#ifdef GL_EXT_geometry_shader\n"
+ << "#extension GL_EXT_geometry_shader : " << GetBehaviorString(iter->second)
+ << "\n"
+ << "#elif defined GL_OES_geometry_shader\n"
+ << "#extension GL_OES_geometry_shader : " << GetBehaviorString(iter->second)
+ << "\n";
+ if (iter->second == EBhRequire)
+ {
+ sink << "#else\n"
+ << "#error \"No geometry shader extensions available.\" // Only generate "
+ "this if the extension is \"required\"\n";
+ }
+ sink << "#endif\n";
+ }
+ else if (iter->first == TExtension::ANGLE_multi_draw)
+ {
+ // Don't emit anything. This extension is emulated
+ ASSERT(compileOptions.emulateGLDrawID);
+ continue;
+ }
+ else if (iter->first == TExtension::ANGLE_base_vertex_base_instance_shader_builtin)
+ {
+ // Don't emit anything. This extension is emulated
+ ASSERT(compileOptions.emulateGLBaseVertexBaseInstance);
+ continue;
+ }
+ else if (iter->first == TExtension::ANGLE_shader_pixel_local_storage)
+ {
+ // TODO(anglebug.com/7279): future impl that uses EXT_shader_pixel_local_storage.
+ if (compileOptions.pls.type == ShPixelLocalStorageType::FramebufferFetch)
+ {
+ // Just enable the extension. Appropriate warnings will be generated by the
+ // frontend compiler for GL_ANGLE_shader_pixel_local_storage, if desired.
+ sink << "#extension GL_EXT_shader_framebuffer_fetch : enable\n";
+ }
+ continue;
+ }
+ else if (iter->first == TExtension::EXT_shader_framebuffer_fetch)
+ {
+ sink << "#extension GL_EXT_shader_framebuffer_fetch : "
+ << GetBehaviorString(iter->second) << "\n";
+ continue;
+ }
+ else if (iter->first == TExtension::EXT_shader_framebuffer_fetch_non_coherent)
+ {
+ sink << "#extension GL_EXT_shader_framebuffer_fetch_non_coherent : "
+ << GetBehaviorString(iter->second) << "\n";
+ continue;
+ }
+ else if (iter->first == TExtension::WEBGL_video_texture)
+ {
+ // Don't emit anything. This extension is emulated
+ // TODO(crbug.com/776222): support external image.
+ continue;
+ }
+ else
+ {
+ sink << "#extension " << GetExtensionNameString(iter->first) << " : "
+ << GetBehaviorString(iter->second) << "\n";
+ }
+ }
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.h b/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.h
new file mode 100644
index 0000000000..913d441364
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.h
@@ -0,0 +1,35 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TRANSLATORESSL_H_
+#define COMPILER_TRANSLATOR_TRANSLATORESSL_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TranslatorESSL : public TCompiler
+{
+ public:
+ TranslatorESSL(sh::GLenum type, ShShaderSpec spec);
+
+ protected:
+ void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
+ const ShCompileOptions &compileOptions) override;
+
+ [[nodiscard]] bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+ bool shouldFlattenPragmaStdglInvariantAll() override;
+
+ private:
+ void writeExtensionBehavior(const ShCompileOptions &compileOptions);
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORESSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp
new file mode 100644
index 0000000000..76e0130e77
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp
@@ -0,0 +1,388 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/TranslatorGLSL.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
+#include "compiler/translator/ExtensionGLSL.h"
+#include "compiler/translator/OutputGLSL.h"
+#include "compiler/translator/VersionGLSL.h"
+#include "compiler/translator/tree_ops/RewriteTexelFetchOffset.h"
+#include "compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h"
+#include "compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.h"
+
+namespace sh
+{
+
+TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
+ : TCompiler(type, spec, output)
+{}
+
+void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
+ const ShCompileOptions &compileOptions)
+{
+ if (compileOptions.emulateAbsIntFunction)
+ {
+ InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(emu, getShaderType());
+ }
+
+ if (compileOptions.emulateIsnanFloatFunction)
+ {
+ InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(emu, getShaderVersion());
+ }
+
+ if (compileOptions.emulateAtan2FloatFunction)
+ {
+ InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(emu);
+ }
+
+ int targetGLSLVersion = ShaderOutputTypeToGLSLVersion(getOutputType());
+ InitBuiltInFunctionEmulatorForGLSLMissingFunctions(emu, getShaderType(), targetGLSLVersion);
+}
+
+bool TranslatorGLSL::translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics * /*perfDiagnostics*/)
+{
+ TInfoSinkBase &sink = getInfoSink().obj;
+
+ // Write GLSL version.
+ writeVersion(root);
+
+ // Write extension behaviour as needed
+ writeExtensionBehavior(root, compileOptions);
+
+ // Write pragmas after extensions because some drivers consider pragmas
+ // like non-preprocessor tokens.
+ WritePragma(sink, compileOptions, getPragma());
+
+ // If flattening the global invariant pragma, write invariant declarations for built-in
+ // variables. It should be harmless to do this twice in the case that the shader also explicitly
+ // did this. However, it's important to emit invariant qualifiers only for those built-in
+ // variables that are actually used, to avoid affecting the behavior of the shader.
+ if (compileOptions.flattenPragmaSTDGLInvariantAll && getPragma().stdgl.invariantAll &&
+ !sh::RemoveInvariant(getShaderType(), getShaderVersion(), getOutputType(), compileOptions))
+ {
+ ASSERT(wereVariablesCollected());
+
+ switch (getShaderType())
+ {
+ case GL_VERTEX_SHADER:
+ sink << "invariant gl_Position;\n";
+
+ // gl_PointSize should be declared invariant in both ESSL 1.00 and 3.00 fragment
+ // shaders if it's statically referenced.
+ conditionallyOutputInvariantDeclaration("gl_PointSize");
+ break;
+ case GL_FRAGMENT_SHADER:
+ // The preprocessor will reject this pragma if it's used in ESSL 3.00 fragment
+ // shaders, so we can use simple logic to determine whether to declare these
+ // variables invariant.
+ conditionallyOutputInvariantDeclaration("gl_FragCoord");
+ conditionallyOutputInvariantDeclaration("gl_PointCoord");
+ break;
+ default:
+ // Currently not reached, but leave this in for future expansion.
+ ASSERT(false);
+ break;
+ }
+ }
+
+ if (compileOptions.rewriteTexelFetchOffsetToTexelFetch)
+ {
+ if (!sh::RewriteTexelFetchOffset(this, root, getSymbolTable(), getShaderVersion()))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.rewriteFloatUnaryMinusOperator)
+ {
+ if (!sh::RewriteUnaryMinusOperatorFloat(this, root))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.rewriteRowMajorMatrices && getShaderVersion() >= 300)
+ {
+ if (!RewriteRowMajorMatrices(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ // Write emulated built-in functions if needed.
+ if (!getBuiltInFunctionEmulator().isOutputEmpty())
+ {
+ sink << "// BEGIN: Generated code for built-in function emulation\n\n";
+ sink << "#define emu_precision\n\n";
+ getBuiltInFunctionEmulator().outputEmulatedFunctions(sink);
+ sink << "// END: Generated code for built-in function emulation\n\n";
+ }
+
+ // Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData
+ // if it's core profile shaders and they are used.
+ if (getShaderType() == GL_FRAGMENT_SHADER)
+ {
+ const bool mayHaveESSL1SecondaryOutputs =
+ IsExtensionEnabled(getExtensionBehavior(), TExtension::EXT_blend_func_extended) &&
+ getShaderVersion() == 100;
+ const bool declareGLFragmentOutputs = IsGLSL130OrNewer(getOutputType());
+
+ bool hasGLFragColor = false;
+ bool hasGLFragData = false;
+ bool hasGLSecondaryFragColor = false;
+ bool hasGLSecondaryFragData = false;
+
+ for (const auto &outputVar : mOutputVariables)
+ {
+ if (declareGLFragmentOutputs)
+ {
+ if (outputVar.name == "gl_FragColor")
+ {
+ ASSERT(!hasGLFragColor);
+ hasGLFragColor = true;
+ continue;
+ }
+ else if (outputVar.name == "gl_FragData")
+ {
+ ASSERT(!hasGLFragData);
+ hasGLFragData = true;
+ continue;
+ }
+ }
+ if (mayHaveESSL1SecondaryOutputs)
+ {
+ if (outputVar.name == "gl_SecondaryFragColorEXT")
+ {
+ ASSERT(!hasGLSecondaryFragColor);
+ hasGLSecondaryFragColor = true;
+ continue;
+ }
+ else if (outputVar.name == "gl_SecondaryFragDataEXT")
+ {
+ ASSERT(!hasGLSecondaryFragData);
+ hasGLSecondaryFragData = true;
+ continue;
+ }
+ }
+ }
+ ASSERT(!((hasGLFragColor || hasGLSecondaryFragColor) &&
+ (hasGLFragData || hasGLSecondaryFragData)));
+ if (hasGLFragColor)
+ {
+ sink << "out vec4 webgl_FragColor;\n";
+ }
+ if (hasGLFragData)
+ {
+ sink << "out vec4 webgl_FragData[gl_MaxDrawBuffers];\n";
+ }
+ if (hasGLSecondaryFragColor)
+ {
+ sink << "out vec4 webgl_SecondaryFragColor;\n";
+ }
+ if (hasGLSecondaryFragData)
+ {
+ sink << "out vec4 webgl_SecondaryFragData[" << getResources().MaxDualSourceDrawBuffers
+ << "];\n";
+ }
+
+ EmitEarlyFragmentTestsGLSL(*this, sink);
+ }
+
+ if (getShaderType() == GL_COMPUTE_SHADER)
+ {
+ EmitWorkGroupSizeGLSL(*this, sink);
+ }
+
+ if (getShaderType() == GL_GEOMETRY_SHADER_EXT)
+ {
+ WriteGeometryShaderLayoutQualifiers(
+ sink, getGeometryShaderInputPrimitiveType(), getGeometryShaderInvocations(),
+ getGeometryShaderOutputPrimitiveType(), getGeometryShaderMaxVertices());
+ }
+
+ // Write translated shader.
+ TOutputGLSL outputGLSL(this, sink, compileOptions);
+
+ root->traverse(&outputGLSL);
+
+ return true;
+}
+
+bool TranslatorGLSL::shouldFlattenPragmaStdglInvariantAll()
+{
+ // Required when outputting to any GLSL version greater than 1.20, but since ANGLE doesn't
+ // translate to that version, return true for the next higher version.
+ return IsGLSL130OrNewer(getOutputType());
+}
+
+bool TranslatorGLSL::shouldCollectVariables(const ShCompileOptions &compileOptions)
+{
+ return compileOptions.flattenPragmaSTDGLInvariantAll ||
+ TCompiler::shouldCollectVariables(compileOptions);
+}
+
+void TranslatorGLSL::writeVersion(TIntermNode *root)
+{
+ TVersionGLSL versionGLSL(getShaderType(), getPragma(), getOutputType());
+ root->traverse(&versionGLSL);
+ int version = versionGLSL.getVersion();
+ // We need to write version directive only if it is greater than 110.
+ // If there is no version directive in the shader, 110 is implied.
+ if (version > 110)
+ {
+ TInfoSinkBase &sink = getInfoSink().obj;
+ sink << "#version " << version << "\n";
+ }
+}
+
+void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root,
+ const ShCompileOptions &compileOptions)
+{
+ bool usesTextureCubeMapArray = false;
+ bool usesTextureBuffer = false;
+
+ TInfoSinkBase &sink = getInfoSink().obj;
+ const TExtensionBehavior &extBehavior = getExtensionBehavior();
+ for (const auto &iter : extBehavior)
+ {
+ if (iter.second == EBhUndefined)
+ {
+ continue;
+ }
+
+ if (getOutputType() == SH_GLSL_COMPATIBILITY_OUTPUT)
+ {
+ // For GLSL output, we don't need to emit most extensions explicitly,
+ // but some we need to translate in GL compatibility profile.
+ if (iter.first == TExtension::EXT_shader_texture_lod)
+ {
+ sink << "#extension GL_ARB_shader_texture_lod : " << GetBehaviorString(iter.second)
+ << "\n";
+ }
+
+ if (iter.first == TExtension::EXT_draw_buffers)
+ {
+ sink << "#extension GL_ARB_draw_buffers : " << GetBehaviorString(iter.second)
+ << "\n";
+ }
+
+ if (iter.first == TExtension::EXT_geometry_shader ||
+ iter.first == TExtension::OES_geometry_shader)
+ {
+ sink << "#extension GL_ARB_geometry_shader4 : " << GetBehaviorString(iter.second)
+ << "\n";
+ }
+ }
+
+ const bool isMultiview =
+ (iter.first == TExtension::OVR_multiview) || (iter.first == TExtension::OVR_multiview2);
+ if (isMultiview)
+ {
+ // Only either OVR_multiview or OVR_multiview2 should be emitted.
+ if ((iter.first != TExtension::OVR_multiview) ||
+ !IsExtensionEnabled(extBehavior, TExtension::OVR_multiview2))
+ {
+ EmitMultiviewGLSL(*this, compileOptions, iter.first, iter.second, sink);
+ }
+ }
+
+ // Support ANGLE_texture_multisample extension on GLSL300
+ if (getShaderVersion() >= 300 && iter.first == TExtension::ANGLE_texture_multisample &&
+ getOutputType() < SH_GLSL_330_CORE_OUTPUT)
+ {
+ sink << "#extension GL_ARB_texture_multisample : " << GetBehaviorString(iter.second)
+ << "\n";
+ }
+
+ if ((iter.first == TExtension::OES_texture_cube_map_array ||
+ iter.first == TExtension::EXT_texture_cube_map_array) &&
+ (iter.second == EBhRequire || iter.second == EBhEnable))
+ {
+ usesTextureCubeMapArray = true;
+ }
+
+ if ((iter.first == TExtension::OES_texture_buffer ||
+ iter.first == TExtension::EXT_texture_buffer) &&
+ (iter.second == EBhRequire || iter.second == EBhEnable))
+ {
+ usesTextureBuffer = true;
+ }
+ }
+
+ // GLSL ES 3 explicit location qualifiers need to use an extension before GLSL 330
+ if (getShaderVersion() >= 300 && getOutputType() < SH_GLSL_330_CORE_OUTPUT &&
+ getShaderType() != GL_COMPUTE_SHADER)
+ {
+ sink << "#extension GL_ARB_explicit_attrib_location : require\n";
+ }
+
+ // Need to enable gpu_shader5 to have index constant sampler array indexing
+ if (getOutputType() != SH_ESSL_OUTPUT && getOutputType() < SH_GLSL_400_CORE_OUTPUT &&
+ getShaderVersion() == 100)
+ {
+ // Don't use "require" on to avoid breaking WebGL 1 on drivers that silently
+ // support index constant sampler array indexing, but don't have the extension or
+ // on drivers that don't have the extension at all as it would break WebGL 1 for
+ // some users.
+ sink << "#extension GL_ARB_gpu_shader5 : enable\n";
+ sink << "#extension GL_EXT_gpu_shader5 : enable\n";
+ }
+
+ if (usesTextureCubeMapArray)
+ {
+ if (getOutputType() >= SH_GLSL_COMPATIBILITY_OUTPUT &&
+ getOutputType() < SH_GLSL_400_CORE_OUTPUT)
+ {
+ sink << "#extension GL_ARB_texture_cube_map_array : enable\n";
+ }
+ else if (getOutputType() == SH_ESSL_OUTPUT && getShaderVersion() < 320)
+ {
+ sink << "#extension GL_OES_texture_cube_map_array : enable\n";
+ sink << "#extension GL_EXT_texture_cube_map_array : enable\n";
+ }
+ }
+
+ if (usesTextureBuffer)
+ {
+ if (getOutputType() >= SH_GLSL_COMPATIBILITY_OUTPUT &&
+ getOutputType() < SH_GLSL_400_CORE_OUTPUT)
+ {
+ sink << "#extension GL_ARB_texture_buffer_objects : enable\n";
+ }
+ else if (getOutputType() == SH_ESSL_OUTPUT && getShaderVersion() < 320)
+ {
+ sink << "#extension GL_OES_texture_buffer : enable\n";
+ sink << "#extension GL_EXT_texture_buffer : enable\n";
+ }
+ }
+
+ TExtensionGLSL extensionGLSL(getOutputType());
+ root->traverse(&extensionGLSL);
+
+ for (const auto &ext : extensionGLSL.getEnabledExtensions())
+ {
+ sink << "#extension " << ext << " : enable\n";
+ }
+ for (const auto &ext : extensionGLSL.getRequiredExtensions())
+ {
+ sink << "#extension " << ext << " : require\n";
+ }
+}
+
+void TranslatorGLSL::conditionallyOutputInvariantDeclaration(const char *builtinVaryingName)
+{
+ if (isVaryingDefined(builtinVaryingName))
+ {
+ TInfoSinkBase &sink = getInfoSink().obj;
+ sink << "invariant " << builtinVaryingName << ";\n";
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.h b/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.h
new file mode 100644
index 0000000000..0e0c65f09a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TRANSLATORGLSL_H_
+#define COMPILER_TRANSLATOR_TRANSLATORGLSL_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TranslatorGLSL : public TCompiler
+{
+ public:
+ TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
+
+ protected:
+ void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
+ const ShCompileOptions &compileOptions) override;
+
+ [[nodiscard]] bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+ bool shouldFlattenPragmaStdglInvariantAll() override;
+ bool shouldCollectVariables(const ShCompileOptions &compileOptions) override;
+
+ private:
+ void writeVersion(TIntermNode *root);
+ void writeExtensionBehavior(TIntermNode *root, const ShCompileOptions &compileOptions);
+ void conditionallyOutputInvariantDeclaration(const char *builtinVaryingName);
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp
new file mode 100644
index 0000000000..d07ed2975e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp
@@ -0,0 +1,311 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/TranslatorHLSL.h"
+
+#include "compiler/translator/OutputHLSL.h"
+#include "compiler/translator/tree_ops/RemoveDynamicIndexing.h"
+#include "compiler/translator/tree_ops/RewriteTexelFetchOffset.h"
+#include "compiler/translator/tree_ops/SimplifyLoopConditions.h"
+#include "compiler/translator/tree_ops/SplitSequenceOperator.h"
+#include "compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h"
+#include "compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h"
+#include "compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.h"
+#include "compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h"
+#include "compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h"
+#include "compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.h"
+#include "compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h"
+#include "compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h"
+#include "compiler/translator/tree_ops/d3d/RewriteElseBlocks.h"
+#include "compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h"
+#include "compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h"
+#include "compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h"
+#include "compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h"
+#include "compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h"
+#include "compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h"
+#include "compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+
+namespace sh
+{
+
+TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
+ : TCompiler(type, spec, output)
+{}
+
+bool TranslatorHLSL::translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ // A few transformations leave the tree in an inconsistent state. For example, when unfolding
+ // the short-circuit in the following function:
+ //
+ // mediump float f(float a) { return a > 0 ? 0.0 : 1.0; }
+ //
+ // a temp variable is created to hold the result of the expression. Currently the precision of
+ // the return value of the function is not propagated to its return expressions. Additionally,
+ // an expression such as
+ //
+ // cond ? gl_NumWorkGroups.x : gl_NumWorkGroups.y
+ //
+ // does not have a precision as the built-in does not specify a precision.
+ //
+ // Precision is not applicable to HLSL so fixing these issues are deferred.
+ mValidateASTOptions.validatePrecision = false;
+
+ const ShBuiltInResources &resources = getResources();
+ int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
+ int maxDualSourceDrawBuffers =
+ resources.EXT_blend_func_extended ? resources.MaxDualSourceDrawBuffers : 0;
+
+ if (!sh::AddDefaultReturnStatements(this, root))
+ {
+ return false;
+ }
+
+ // Note that SimplifyLoopConditions needs to be run before any other AST transformations that
+ // may need to generate new statements from loop conditions or loop expressions.
+ // Note that SeparateDeclarations has already been run in TCompiler::compileTreeImpl().
+ if (!SimplifyLoopConditions(
+ this, root,
+ IntermNodePatternMatcher::kExpressionReturningArray |
+ IntermNodePatternMatcher::kUnfoldedShortCircuitExpression |
+ IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue,
+ &getSymbolTable()))
+ {
+ return false;
+ }
+
+ if (!SplitSequenceOperator(
+ this, root,
+ IntermNodePatternMatcher::kExpressionReturningArray |
+ IntermNodePatternMatcher::kUnfoldedShortCircuitExpression |
+ IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue,
+ &getSymbolTable()))
+ {
+ return false;
+ }
+
+ // Note that SeparateDeclarations needs to be run before UnfoldShortCircuitToIf.
+ if (!UnfoldShortCircuitToIf(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+
+ if (!SeparateArrayConstructorStatements(this, root))
+ {
+ return false;
+ }
+
+ if (getShaderVersion() >= 310)
+ {
+ // Do element-by-element assignments of arrays in SSBOs. This allows the D3D backend to use
+ // RWByteAddressBuffer.Load() and .Store(), which only operate on values up to 16 bytes in
+ // size. Note that this must be done before SeparateExpressionsReturningArrays.
+ if (!sh::AggregateAssignArraysInSSBOs(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ // Do field-by-field assignment of structs in SSBOs. This allows the D3D backend to use
+ // RWByteAddressBuffer.Load() and .Store(), which only operate on values up to 16 bytes in
+ // size.
+ if (!sh::AggregateAssignStructsInSSBOs(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (!SeparateExpressionsReturningArrays(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+
+ // Note that SeparateDeclarations needs to be run before SeparateArrayInitialization.
+ if (!SeparateArrayInitialization(this, root))
+ {
+ return false;
+ }
+
+ // HLSL doesn't support arrays as return values, we'll need to make functions that have an array
+ // as a return value to use an out parameter to transfer the array data instead.
+ if (!ArrayReturnValueToOutParameter(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+
+ if (!shouldRunLoopAndIndexingValidation(compileOptions))
+ {
+ // HLSL doesn't support dynamic indexing of vectors and matrices.
+ if (!RemoveDynamicIndexingOfNonSSBOVectorOrMatrix(this, root, &getSymbolTable(),
+ perfDiagnostics))
+ {
+ return false;
+ }
+ }
+
+ // Work around D3D9 bug that would manifest in vertex shaders with selection blocks which
+ // use a vertex attribute as a condition, and some related computation in the else block.
+ if (getOutputType() == SH_HLSL_3_0_OUTPUT && getShaderType() == GL_VERTEX_SHADER)
+ {
+ if (!sh::RewriteElseBlocks(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ // Work around an HLSL compiler frontend aliasing optimization bug.
+ // TODO(cwallez) The date is 2016-08-25, Microsoft said the bug would be fixed
+ // in the next release of d3dcompiler.dll, it would be nice to detect the DLL
+ // version and only apply the workaround if it is too old.
+ if (!sh::BreakVariableAliasingInInnerLoops(this, root))
+ {
+ return false;
+ }
+
+ // WrapSwitchStatementsInBlocks should be called after any AST transformations that might
+ // introduce variable declarations inside the main scope of any switch statement. It cannot
+ // result in no-op cases at the end of switch statements, because unreferenced variables
+ // have already been pruned.
+ if (!WrapSwitchStatementsInBlocks(this, root))
+ {
+ return false;
+ }
+
+ if (compileOptions.expandSelectHLSLIntegerPowExpressions)
+ {
+ if (!sh::ExpandIntegerPowExpressions(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.rewriteTexelFetchOffsetToTexelFetch)
+ {
+ if (!sh::RewriteTexelFetchOffset(this, root, getSymbolTable(), getShaderVersion()))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.rewriteIntegerUnaryMinusOperator && getShaderType() == GL_VERTEX_SHADER)
+ {
+ if (!sh::RewriteUnaryMinusOperatorInt(this, root))
+ {
+ return false;
+ }
+ }
+
+ if (getShaderVersion() >= 310)
+ {
+ // Due to ssbo also can be used as the argument of atomic memory functions, we should put
+ // RewriteExpressionsWithShaderStorageBlock before RewriteAtomicFunctionExpressions.
+ if (!sh::RewriteExpressionsWithShaderStorageBlock(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ if (!sh::RewriteAtomicFunctionExpressions(this, root, &getSymbolTable(),
+ getShaderVersion()))
+ {
+ return false;
+ }
+ }
+
+ mUniformBlockOptimizedMap.clear();
+ mSlowCompilingUniformBlockSet.clear();
+ // In order to get the exact maximum of slots are available for shader resources, which would
+ // been bound with StructuredBuffer, we only translate uniform block with a large array member
+ // into StructuredBuffer when shader version is 300.
+ if (getShaderVersion() == 300 && compileOptions.allowTranslateUniformBlockToStructuredBuffer)
+ {
+ if (!sh::RecordUniformBlocksWithLargeArrayMember(root, mUniformBlockOptimizedMap,
+ mSlowCompilingUniformBlockSet))
+ {
+ return false;
+ }
+ }
+
+ sh::OutputHLSL outputHLSL(
+ getShaderType(), getShaderSpec(), getShaderVersion(), getExtensionBehavior(),
+ getSourcePath(), getOutputType(), numRenderTargets, maxDualSourceDrawBuffers, getUniforms(),
+ compileOptions, getComputeShaderLocalSize(), &getSymbolTable(), perfDiagnostics,
+ mUniformBlockOptimizedMap, mShaderStorageBlocks, isEarlyFragmentTestsSpecified());
+
+ outputHLSL.output(root, getInfoSink().obj);
+
+ mShaderStorageBlockRegisterMap = outputHLSL.getShaderStorageBlockRegisterMap();
+ mUniformBlockRegisterMap = outputHLSL.getUniformBlockRegisterMap();
+ mUniformBlockUseStructuredBufferMap = outputHLSL.getUniformBlockUseStructuredBufferMap();
+ mUniformRegisterMap = outputHLSL.getUniformRegisterMap();
+ mReadonlyImage2DRegisterIndex = outputHLSL.getReadonlyImage2DRegisterIndex();
+ mImage2DRegisterIndex = outputHLSL.getImage2DRegisterIndex();
+ mUsedImage2DFunctionNames = outputHLSL.getUsedImage2DFunctionNames();
+
+ return true;
+}
+
+bool TranslatorHLSL::shouldFlattenPragmaStdglInvariantAll()
+{
+ // Not necessary when translating to HLSL.
+ return false;
+}
+
+bool TranslatorHLSL::hasShaderStorageBlock(const std::string &uniformBlockName) const
+{
+ return (mShaderStorageBlockRegisterMap.count(uniformBlockName) > 0);
+}
+
+unsigned int TranslatorHLSL::getShaderStorageBlockRegister(
+ const std::string &shaderStorageBlockName) const
+{
+ ASSERT(hasShaderStorageBlock(shaderStorageBlockName));
+ return mShaderStorageBlockRegisterMap.find(shaderStorageBlockName)->second;
+}
+
+bool TranslatorHLSL::hasUniformBlock(const std::string &uniformBlockName) const
+{
+ return (mUniformBlockRegisterMap.count(uniformBlockName) > 0);
+}
+
+unsigned int TranslatorHLSL::getUniformBlockRegister(const std::string &uniformBlockName) const
+{
+ ASSERT(hasUniformBlock(uniformBlockName));
+ return mUniformBlockRegisterMap.find(uniformBlockName)->second;
+}
+
+const std::map<std::string, unsigned int> *TranslatorHLSL::getUniformRegisterMap() const
+{
+ return &mUniformRegisterMap;
+}
+
+const std::set<std::string> *TranslatorHLSL::getSlowCompilingUniformBlockSet() const
+{
+ return &mSlowCompilingUniformBlockSet;
+}
+
+unsigned int TranslatorHLSL::getReadonlyImage2DRegisterIndex() const
+{
+ return mReadonlyImage2DRegisterIndex;
+}
+
+unsigned int TranslatorHLSL::getImage2DRegisterIndex() const
+{
+ return mImage2DRegisterIndex;
+}
+
+const std::set<std::string> *TranslatorHLSL::getUsedImage2DFunctionNames() const
+{
+ return &mUsedImage2DFunctionNames;
+}
+
+bool TranslatorHLSL::shouldUniformBlockUseStructuredBuffer(
+ const std::string &uniformBlockName) const
+{
+ auto uniformBlockIter = mUniformBlockUseStructuredBufferMap.find(uniformBlockName);
+ return uniformBlockIter != mUniformBlockUseStructuredBufferMap.end() &&
+ uniformBlockIter->second;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.h b/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.h
new file mode 100644
index 0000000000..309176bed8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.h
@@ -0,0 +1,56 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TRANSLATORHLSL_H_
+#define COMPILER_TRANSLATOR_TRANSLATORHLSL_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TranslatorHLSL : public TCompiler
+{
+ public:
+ TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
+ TranslatorHLSL *getAsTranslatorHLSL() override { return this; }
+
+ bool hasShaderStorageBlock(const std::string &interfaceBlockName) const;
+ unsigned int getShaderStorageBlockRegister(const std::string &interfaceBlockName) const;
+
+ bool hasUniformBlock(const std::string &interfaceBlockName) const;
+ unsigned int getUniformBlockRegister(const std::string &interfaceBlockName) const;
+ bool shouldUniformBlockUseStructuredBuffer(const std::string &uniformBlockName) const;
+ const std::set<std::string> *getSlowCompilingUniformBlockSet() const;
+
+ const std::map<std::string, unsigned int> *getUniformRegisterMap() const;
+ unsigned int getReadonlyImage2DRegisterIndex() const;
+ unsigned int getImage2DRegisterIndex() const;
+ const std::set<std::string> *getUsedImage2DFunctionNames() const;
+
+ protected:
+ [[nodiscard]] bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+ bool shouldFlattenPragmaStdglInvariantAll() override;
+
+ // collectVariables needs to be run always so registers can be assigned.
+ bool shouldCollectVariables(const ShCompileOptions &compileOptions) override { return true; }
+
+ std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap;
+ std::map<std::string, unsigned int> mUniformBlockRegisterMap;
+ std::map<std::string, bool> mUniformBlockUseStructuredBufferMap;
+ std::map<std::string, unsigned int> mUniformRegisterMap;
+ unsigned int mReadonlyImage2DRegisterIndex;
+ unsigned int mImage2DRegisterIndex;
+ std::set<std::string> mUsedImage2DFunctionNames;
+ std::map<int, const TInterfaceBlock *> mUniformBlockOptimizedMap;
+ std::set<std::string> mSlowCompilingUniformBlockSet;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorMetal.h b/gfx/angle/checkout/src/compiler/translator/TranslatorMetal.h
new file mode 100644
index 0000000000..32b7564f34
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorMetal.h
@@ -0,0 +1,62 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// TranslatorMetal:
+// A GLSL-based translator that outputs shaders that fit GL_KHR_vulkan_glsl.
+// It takes into account some considerations for Metal backend also.
+// The shaders are then fed into glslang to spit out SPIR-V.
+// See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt
+//
+// The SPIR-V will then be translated to Metal Shading Language later in Metal backend.
+//
+
+#ifndef LIBANGLE_RENDERER_METAL_TRANSLATORMETAL_H_
+#define LIBANGLE_RENDERER_METAL_TRANSLATORMETAL_H_
+
+#include "compiler/translator/DriverUniformMetal.h"
+#include "compiler/translator/TranslatorVulkan.h"
+#include "compiler/translator/tree_util/DriverUniform.h"
+#include "compiler/translator/tree_util/SpecializationConstant.h"
+
+namespace sh
+{
+
+// TODO: http://anglebug.com/5339 Implement it using actual specialization constant. For now we are
+// redirecting to driver uniforms
+class SpecConstMetal : public SpecConst
+{
+ public:
+ SpecConstMetal(TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ GLenum shaderType)
+ : SpecConst(symbolTable, compileOptions, shaderType)
+ {}
+ ~SpecConstMetal() override {}
+
+ private:
+};
+
+class TranslatorMetal : public TranslatorVulkan
+{
+ public:
+ TranslatorMetal(sh::GLenum type, ShShaderSpec spec);
+
+ protected:
+ [[nodiscard]] bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+
+ [[nodiscard]] bool transformDepthBeforeCorrection(TIntermBlock *root,
+ const DriverUniform *driverUniforms) override;
+
+ [[nodiscard]] bool insertSampleMaskWritingLogic(TInfoSinkBase &sink,
+ TIntermBlock *root,
+ const DriverUniformMetal *driverUniforms);
+ [[nodiscard]] bool insertRasterizerDiscardLogic(TInfoSinkBase &sink, TIntermBlock *root);
+};
+
+} // namespace sh
+
+#endif /* LIBANGLE_RENDERER_METAL_TRANSLATORMETAL_H_ */
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorMetalDirect.h b/gfx/angle/checkout/src/compiler/translator/TranslatorMetalDirect.h
new file mode 100644
index 0000000000..679687df07
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorMetalDirect.h
@@ -0,0 +1,195 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_H_
+#define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+constexpr const char kUniformsVar[] = "angleUniforms";
+constexpr const char kUnassignedAttributeString[] = " __unassigned_attribute__";
+
+class DriverUniform;
+class DriverUniformMetal;
+class SpecConst;
+class TOutputMSL;
+class TranslatorMetalReflection;
+typedef std::unordered_map<size_t, std::string> originalNamesMap;
+typedef std::unordered_map<std::string, size_t> samplerBindingMap;
+typedef std::unordered_map<std::string, size_t> textureBindingMap;
+typedef std::unordered_map<std::string, size_t> userUniformBufferBindingMap;
+typedef std::pair<size_t, size_t> uboBindingInfo;
+struct UBOBindingInfo
+{
+ size_t bindIndex = 0;
+ size_t arraySize = 0;
+};
+typedef std::unordered_map<std::string, UBOBindingInfo> uniformBufferBindingMap;
+
+namespace mtl
+{
+TranslatorMetalReflection *getTranslatorMetalReflection(const TCompiler *compiler);
+}
+
+class TranslatorMetalReflection
+{
+ public:
+ TranslatorMetalReflection() : hasUBOs(false), hasFlatInput(false) {}
+ ~TranslatorMetalReflection() {}
+
+ void addOriginalName(const size_t id, const std::string &name)
+ {
+ originalNames.insert({id, name});
+ }
+ void addSamplerBinding(const std::string &name, size_t samplerBinding)
+ {
+ samplerBindings.insert({name, samplerBinding});
+ }
+ void addTextureBinding(const std::string &name, size_t textureBinding)
+ {
+ textureBindings.insert({name, textureBinding});
+ }
+ void addUserUniformBufferBinding(const std::string &name, size_t userUniformBufferBinding)
+ {
+ userUniformBufferBindings.insert({name, userUniformBufferBinding});
+ }
+ void addUniformBufferBinding(const std::string &name, UBOBindingInfo bindingInfo)
+ {
+ uniformBufferBindings.insert({name, bindingInfo});
+ }
+ std::string getOriginalName(const size_t id) { return originalNames.at(id); }
+ samplerBindingMap getSamplerBindings() const { return samplerBindings; }
+ textureBindingMap getTextureBindings() const { return textureBindings; }
+ userUniformBufferBindingMap getUserUniformBufferBindings() const
+ {
+ return userUniformBufferBindings;
+ }
+ uniformBufferBindingMap getUniformBufferBindings() const { return uniformBufferBindings; }
+ size_t getSamplerBinding(const std::string &name) const
+ {
+ auto it = samplerBindings.find(name);
+ if (it != samplerBindings.end())
+ {
+ return it->second;
+ }
+ // If we can't find a matching sampler, assert out on Debug, and return an invalid value on
+ // release.
+ ASSERT(0);
+ return std::numeric_limits<size_t>::max();
+ }
+ size_t getTextureBinding(const std::string &name) const
+ {
+ auto it = textureBindings.find(name);
+ if (it != textureBindings.end())
+ {
+ return it->second;
+ }
+ // If we can't find a matching texture, assert out on Debug, and return an invalid value on
+ // release.
+ ASSERT(0);
+ return std::numeric_limits<size_t>::max();
+ }
+ size_t getUserUniformBufferBinding(const std::string &name) const
+ {
+ auto it = userUniformBufferBindings.find(name);
+ if (it != userUniformBufferBindings.end())
+ {
+ return it->second;
+ }
+ // If we can't find a matching Uniform binding, assert out on Debug, and return an invalid
+ // value.
+ ASSERT(0);
+ return std::numeric_limits<size_t>::max();
+ }
+ UBOBindingInfo getUniformBufferBinding(const std::string &name) const
+ {
+ auto it = uniformBufferBindings.find(name);
+ if (it != uniformBufferBindings.end())
+ {
+ return it->second;
+ }
+ // If we can't find a matching UBO binding by name, assert out on Debug, and return an
+ // invalid value.
+ ASSERT(0);
+ return {.bindIndex = std::numeric_limits<size_t>::max(),
+ .arraySize = std::numeric_limits<size_t>::max()};
+ }
+ void reset()
+ {
+ hasUBOs = false;
+ hasFlatInput = false;
+ hasAtan = false;
+ hasInvariance = false;
+ originalNames.clear();
+ samplerBindings.clear();
+ textureBindings.clear();
+ userUniformBufferBindings.clear();
+ uniformBufferBindings.clear();
+ }
+
+ bool hasUBOs = false;
+ bool hasFlatInput = false;
+ bool hasAtan = false;
+ bool hasInvariance = false;
+
+ private:
+ originalNamesMap originalNames;
+ samplerBindingMap samplerBindings;
+ textureBindingMap textureBindings;
+ userUniformBufferBindingMap userUniformBufferBindings;
+ uniformBufferBindingMap uniformBufferBindings;
+};
+
+class TranslatorMetalDirect : public TCompiler
+{
+ public:
+ TranslatorMetalDirect(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
+
+#ifdef ANGLE_ENABLE_METAL
+ TranslatorMetalDirect *getAsTranslatorMetalDirect() override { return this; }
+#endif
+
+ TranslatorMetalReflection *getTranslatorMetalReflection() { return &translatorMetalReflection; }
+
+ protected:
+ bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+
+ // The sample mask can't be in our fragment output struct if we read the framebuffer. Luckily,
+ // pixel local storage bans gl_SampleMask, so we can just not use it when PLS is active.
+ bool usesSampleMask() const { return !hasPixelLocalStorageUniforms(); }
+
+ // Need to collect variables so that RemoveInactiveInterfaceVariables works.
+ bool shouldCollectVariables(const ShCompileOptions &compileOptions) override { return true; }
+
+ [[nodiscard]] bool translateImpl(TInfoSinkBase &sink,
+ TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics,
+ SpecConst *specConst,
+ DriverUniformMetal *driverUniforms);
+
+ [[nodiscard]] bool shouldFlattenPragmaStdglInvariantAll() override;
+
+ [[nodiscard]] bool transformDepthBeforeCorrection(TIntermBlock *root,
+ const DriverUniformMetal *driverUniforms);
+
+ [[nodiscard]] bool appendVertexShaderDepthCorrectionToMain(TIntermBlock *root);
+
+ [[nodiscard]] bool insertSampleMaskWritingLogic(TIntermBlock &root,
+ DriverUniformMetal &driverUniforms);
+ [[nodiscard]] bool insertRasterizationDiscardLogic(TIntermBlock &root);
+
+ TranslatorMetalReflection translatorMetalReflection = {};
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorVulkan.h b/gfx/angle/checkout/src/compiler/translator/TranslatorVulkan.h
new file mode 100644
index 0000000000..db80f499e8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorVulkan.h
@@ -0,0 +1,60 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// TranslatorVulkan:
+// A GLSL-based translator that outputs shaders that fit GL_KHR_vulkan_glsl and feeds them into
+// glslang to spit out SPIR-V.
+// See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt
+//
+
+#ifndef COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_
+#define COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TOutputVulkanGLSL;
+class SpecConst;
+class DriverUniform;
+
+class TranslatorVulkan : public TCompiler
+{
+ public:
+ TranslatorVulkan(sh::GLenum type, ShShaderSpec spec);
+
+ protected:
+ [[nodiscard]] bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+ bool shouldFlattenPragmaStdglInvariantAll() override;
+
+ // Subclass can call this method to transform the AST before writing the final output.
+ // See TranslatorMetal.cpp.
+ [[nodiscard]] bool translateImpl(TInfoSinkBase &sink,
+ TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics,
+ SpecConst *specConst,
+ DriverUniform *driverUniforms);
+
+ void writeExtensionBehavior(const ShCompileOptions &compileOptions, TInfoSinkBase &sink);
+
+ // Give subclass such as TranslatorMetal a chance to do depth transform before
+ // TranslatorVulkan apply its own transform.
+ [[nodiscard]] virtual bool transformDepthBeforeCorrection(TIntermBlock *root,
+ const DriverUniform *driverUniforms)
+ {
+ return true;
+ }
+
+ // Generate SPIR-V out of intermediate GLSL through glslang.
+ [[nodiscard]] bool compileToSpirv(const TInfoSinkBase &glsl);
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Types.cpp b/gfx/angle/checkout/src/compiler/translator/Types.cpp
new file mode 100644
index 0000000000..c1d57fdaef
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Types.cpp
@@ -0,0 +1,984 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#if defined(_MSC_VER)
+# pragma warning(disable : 4718)
+#endif
+
+#include "compiler/translator/Types.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+
+#include <algorithm>
+#include <climits>
+
+namespace sh
+{
+
+const char *getBasicString(TBasicType t)
+{
+ switch (t)
+ {
+ case EbtVoid:
+ return "void";
+ case EbtFloat:
+ return "float";
+ case EbtInt:
+ return "int";
+ case EbtUInt:
+ return "uint";
+ case EbtBool:
+ return "bool";
+ case EbtYuvCscStandardEXT:
+ return "yuvCscStandardEXT";
+ case EbtSampler2D:
+ return "sampler2D";
+ case EbtSampler3D:
+ return "sampler3D";
+ case EbtSamplerCube:
+ return "samplerCube";
+ case EbtSamplerExternalOES:
+ return "samplerExternalOES";
+ case EbtSamplerExternal2DY2YEXT:
+ return "__samplerExternal2DY2YEXT";
+ case EbtSampler2DRect:
+ return "sampler2DRect";
+ case EbtSampler2DArray:
+ return "sampler2DArray";
+ case EbtSampler2DMS:
+ return "sampler2DMS";
+ case EbtSampler2DMSArray:
+ return "sampler2DMSArray";
+ case EbtSamplerCubeArray:
+ return "samplerCubeArray";
+ case EbtSamplerBuffer:
+ return "samplerBuffer";
+ case EbtISampler2D:
+ return "isampler2D";
+ case EbtISampler3D:
+ return "isampler3D";
+ case EbtISamplerCube:
+ return "isamplerCube";
+ case EbtISampler2DArray:
+ return "isampler2DArray";
+ case EbtISampler2DMS:
+ return "isampler2DMS";
+ case EbtISampler2DMSArray:
+ return "isampler2DMSArray";
+ case EbtISamplerCubeArray:
+ return "isamplerCubeArray";
+ case EbtISamplerBuffer:
+ return "isamplerBuffer";
+ case EbtUSampler2D:
+ return "usampler2D";
+ case EbtUSampler3D:
+ return "usampler3D";
+ case EbtUSamplerCube:
+ return "usamplerCube";
+ case EbtUSampler2DArray:
+ return "usampler2DArray";
+ case EbtUSampler2DMS:
+ return "usampler2DMS";
+ case EbtUSampler2DMSArray:
+ return "usampler2DMSArray";
+ case EbtUSamplerCubeArray:
+ return "usamplerCubeArray";
+ case EbtUSamplerBuffer:
+ return "usamplerBuffer";
+ case EbtSampler2DShadow:
+ return "sampler2DShadow";
+ case EbtSamplerCubeShadow:
+ return "samplerCubeShadow";
+ case EbtSampler2DArrayShadow:
+ return "sampler2DArrayShadow";
+ case EbtSamplerCubeArrayShadow:
+ return "samplerCubeArrayShadow";
+ case EbtStruct:
+ return "structure";
+ case EbtInterfaceBlock:
+ return "interface block";
+ case EbtImage2D:
+ return "image2D";
+ case EbtIImage2D:
+ return "iimage2D";
+ case EbtUImage2D:
+ return "uimage2D";
+ case EbtImage3D:
+ return "image3D";
+ case EbtIImage3D:
+ return "iimage3D";
+ case EbtUImage3D:
+ return "uimage3D";
+ case EbtImage2DArray:
+ return "image2DArray";
+ case EbtIImage2DArray:
+ return "iimage2DArray";
+ case EbtUImage2DArray:
+ return "uimage2DArray";
+ case EbtImageCube:
+ return "imageCube";
+ case EbtIImageCube:
+ return "iimageCube";
+ case EbtUImageCube:
+ return "uimageCube";
+ case EbtImageCubeArray:
+ return "imageCubeArray";
+ case EbtIImageCubeArray:
+ return "iimageCubeArray";
+ case EbtUImageCubeArray:
+ return "uimageCubeArray";
+ case EbtImageBuffer:
+ return "imageBuffer";
+ case EbtIImageBuffer:
+ return "iimageBuffer";
+ case EbtUImageBuffer:
+ return "uimageBuffer";
+ case EbtAtomicCounter:
+ return "atomic_uint";
+ case EbtSamplerVideoWEBGL:
+ return "samplerVideoWEBGL";
+ case EbtPixelLocalANGLE:
+ return "pixelLocalANGLE";
+ case EbtIPixelLocalANGLE:
+ return "ipixelLocalANGLE";
+ case EbtUPixelLocalANGLE:
+ return "upixelLocalANGLE";
+ case EbtSubpassInput:
+ return "subpassInput";
+ case EbtISubpassInput:
+ return "isubpassInput";
+ case EbtUSubpassInput:
+ return "usubpassInput";
+ case EbtSubpassInputMS:
+ return "subpassInputMS";
+ case EbtISubpassInputMS:
+ return "isubpassInputMS";
+ case EbtUSubpassInputMS:
+ return "usubpassInputMS";
+ default:
+ UNREACHABLE();
+ return "unknown type";
+ }
+}
+
+// TType implementation.
+TType::TType() : TType(EbtVoid, 0, 0) {}
+
+TType::TType(TBasicType t, uint8_t ps, uint8_t ss) : TType(t, EbpUndefined, EvqGlobal, ps, ss) {}
+
+TType::TType(TBasicType t, TPrecision p, TQualifier q, uint8_t ps, uint8_t ss)
+ : TType(t, p, q, ps, ss, TSpan<const unsigned int>(), nullptr)
+{}
+
+TType::TType(const TPublicType &p)
+ : type(p.getBasicType()),
+ precision(p.precision),
+ qualifier(p.qualifier),
+ invariant(p.invariant),
+ precise(p.precise),
+ memoryQualifier(p.memoryQualifier),
+ layoutQualifier(p.layoutQualifier),
+ primarySize(p.getPrimarySize()),
+ secondarySize(p.getSecondarySize()),
+ mArraySizesStorage(nullptr),
+ mInterfaceBlock(nullptr),
+ mStructure(nullptr),
+ mIsStructSpecifier(false),
+ mInterfaceBlockFieldIndex(0),
+ mMangledName(nullptr)
+{
+ ASSERT(primarySize <= 4);
+ ASSERT(secondarySize <= 4);
+ if (p.isArray())
+ {
+ makeArrays(*p.arraySizes);
+ }
+ if (p.getUserDef())
+ {
+ mStructure = p.getUserDef();
+ mIsStructSpecifier = p.isStructSpecifier();
+ }
+}
+
+TType::TType(const TStructure *userDef, bool isStructSpecifier)
+ : TType(EbtStruct, EbpUndefined, EvqTemporary, 1, 1)
+{
+ mStructure = userDef;
+ mIsStructSpecifier = isStructSpecifier;
+}
+
+TType::TType(const TInterfaceBlock *interfaceBlockIn,
+ TQualifier qualifierIn,
+ TLayoutQualifier layoutQualifierIn)
+ : TType(EbtInterfaceBlock, EbpUndefined, qualifierIn, 1, 1)
+{
+ layoutQualifier = layoutQualifierIn;
+ mInterfaceBlock = interfaceBlockIn;
+}
+
+TType::TType(const TType &t)
+{
+ *this = t;
+}
+
+TType &TType::operator=(const TType &t)
+{
+ type = t.type;
+ precision = t.precision;
+ qualifier = t.qualifier;
+ invariant = t.invariant;
+ precise = t.precise;
+ memoryQualifier = t.memoryQualifier;
+ layoutQualifier = t.layoutQualifier;
+ primarySize = t.primarySize;
+ secondarySize = t.secondarySize;
+ mArraySizesStorage = nullptr;
+ mInterfaceBlock = t.mInterfaceBlock;
+ mStructure = t.mStructure;
+ mIsStructSpecifier = t.mIsStructSpecifier;
+ mInterfaceBlockFieldIndex = t.mInterfaceBlockFieldIndex;
+ mMangledName = t.mMangledName;
+
+ if (t.mArraySizesStorage)
+ {
+ // If other type has storage, duplicate the storage and set the view to our own storage.
+ mArraySizesStorage = new TVector<unsigned int>(*t.mArraySizesStorage);
+ mArraySizes = *mArraySizesStorage;
+ }
+ else
+ {
+ // Otherwise reference the same (constexpr) array sizes as the other type.
+ mArraySizes = t.mArraySizes;
+ }
+
+ return *this;
+}
+
+bool TType::canBeConstructed() const
+{
+ switch (type)
+ {
+ case EbtFloat:
+ case EbtInt:
+ case EbtUInt:
+ case EbtBool:
+ case EbtStruct:
+ return true;
+ default:
+ return false;
+ }
+}
+
+const char *TType::getBuiltInTypeNameString() const
+{
+ if (isMatrix())
+ {
+ switch (getCols())
+ {
+ case 2:
+ switch (getRows())
+ {
+ case 2:
+ return "mat2";
+ case 3:
+ return "mat2x3";
+ case 4:
+ return "mat2x4";
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ case 3:
+ switch (getRows())
+ {
+ case 2:
+ return "mat3x2";
+ case 3:
+ return "mat3";
+ case 4:
+ return "mat3x4";
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ case 4:
+ switch (getRows())
+ {
+ case 2:
+ return "mat4x2";
+ case 3:
+ return "mat4x3";
+ case 4:
+ return "mat4";
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ }
+ if (isVector())
+ {
+ switch (getBasicType())
+ {
+ case EbtFloat:
+ switch (getNominalSize())
+ {
+ case 2:
+ return "vec2";
+ case 3:
+ return "vec3";
+ case 4:
+ return "vec4";
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ case EbtInt:
+ switch (getNominalSize())
+ {
+ case 2:
+ return "ivec2";
+ case 3:
+ return "ivec3";
+ case 4:
+ return "ivec4";
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ case EbtBool:
+ switch (getNominalSize())
+ {
+ case 2:
+ return "bvec2";
+ case 3:
+ return "bvec3";
+ case 4:
+ return "bvec4";
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ case EbtUInt:
+ switch (getNominalSize())
+ {
+ case 2:
+ return "uvec2";
+ case 3:
+ return "uvec3";
+ case 4:
+ return "uvec4";
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ }
+ ASSERT(getBasicType() != EbtStruct);
+ ASSERT(getBasicType() != EbtInterfaceBlock);
+ return getBasicString();
+}
+
+int TType::getDeepestStructNesting() const
+{
+ return mStructure ? mStructure->deepestNesting() : 0;
+}
+
+bool TType::isNamelessStruct() const
+{
+ return mStructure && mStructure->symbolType() == SymbolType::Empty;
+}
+
+bool TType::isStructureContainingArrays() const
+{
+ return mStructure ? mStructure->containsArrays() : false;
+}
+
+bool TType::isStructureContainingMatrices() const
+{
+ return mStructure ? mStructure->containsMatrices() : false;
+}
+
+bool TType::isStructureContainingType(TBasicType t) const
+{
+ return mStructure ? mStructure->containsType(t) : false;
+}
+
+bool TType::isStructureContainingSamplers() const
+{
+ return mStructure ? mStructure->containsSamplers() : false;
+}
+
+bool TType::isInterfaceBlockContainingType(TBasicType t) const
+{
+ return isInterfaceBlock() ? mInterfaceBlock->containsType(t) : false;
+}
+
+bool TType::canReplaceWithConstantUnion() const
+{
+ if (isArray())
+ {
+ return false;
+ }
+ if (!mStructure)
+ {
+ return true;
+ }
+ if (isStructureContainingArrays())
+ {
+ return false;
+ }
+ if (getObjectSize() > 16)
+ {
+ return false;
+ }
+ return true;
+}
+
+//
+// Recursively generate mangled names.
+//
+const char *TType::buildMangledName() const
+{
+ TString mangledName(1, GetSizeMangledName(primarySize, secondarySize));
+
+ TBasicMangledName typeName(type);
+ char *basicMangledName = typeName.getName();
+ static_assert(TBasicMangledName::mangledNameSize == 2, "Mangled name size is not 2");
+ if (basicMangledName[0] != '{')
+ {
+ mangledName += basicMangledName[0];
+ mangledName += basicMangledName[1];
+ }
+ else
+ {
+ ASSERT(type == EbtStruct || type == EbtInterfaceBlock);
+ switch (type)
+ {
+ case EbtStruct:
+ mangledName += "{s";
+ if (mStructure->symbolType() != SymbolType::Empty)
+ {
+ mangledName += mStructure->name().data();
+ }
+ mangledName += mStructure->mangledFieldList();
+ mangledName += '}';
+ break;
+ case EbtInterfaceBlock:
+ mangledName += "{i";
+ mangledName += mInterfaceBlock->name().data();
+ mangledName += mInterfaceBlock->mangledFieldList();
+ mangledName += '}';
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+
+ for (unsigned int arraySize : mArraySizes)
+ {
+ char buf[20];
+ snprintf(buf, sizeof(buf), "%d", arraySize);
+ mangledName += 'x';
+ mangledName += buf;
+ }
+
+ // Copy string contents into a pool-allocated buffer, so we never need to call delete.
+ return AllocatePoolCharArray(mangledName.c_str(), mangledName.size());
+}
+
+size_t TType::getObjectSize() const
+{
+ size_t totalSize;
+
+ if (getBasicType() == EbtStruct)
+ totalSize = mStructure->objectSize();
+ else
+ totalSize = primarySize * secondarySize;
+
+ if (totalSize == 0)
+ return 0;
+
+ for (size_t arraySize : mArraySizes)
+ {
+ if (arraySize > INT_MAX / totalSize)
+ totalSize = INT_MAX;
+ else
+ totalSize *= arraySize;
+ }
+
+ return totalSize;
+}
+
+int TType::getLocationCount() const
+{
+ int count = 1;
+
+ if (getBasicType() == EbtStruct)
+ {
+ count = mStructure->getLocationCount();
+ }
+
+ if (count == 0)
+ {
+ return 0;
+ }
+
+ for (unsigned int arraySize : mArraySizes)
+ {
+ if (arraySize > static_cast<unsigned int>(std::numeric_limits<int>::max() / count))
+ {
+ count = std::numeric_limits<int>::max();
+ }
+ else
+ {
+ count *= static_cast<int>(arraySize);
+ }
+ }
+
+ return count;
+}
+
+unsigned int TType::getArraySizeProduct() const
+{
+ unsigned int product = 1u;
+
+ for (unsigned int arraySize : mArraySizes)
+ {
+ product *= arraySize;
+ }
+ return product;
+}
+
+bool TType::isUnsizedArray() const
+{
+ for (unsigned int arraySize : mArraySizes)
+ {
+ if (arraySize == 0u)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TType::sameNonArrayType(const TType &right) const
+{
+ return (type == right.type && primarySize == right.primarySize &&
+ secondarySize == right.secondarySize && mStructure == right.mStructure);
+}
+
+bool TType::isElementTypeOf(const TType &arrayType) const
+{
+ if (!sameNonArrayType(arrayType))
+ {
+ return false;
+ }
+ if (arrayType.getNumArraySizes() != getNumArraySizes() + 1u)
+ {
+ return false;
+ }
+ for (size_t i = 0; i < mArraySizes.size(); ++i)
+ {
+ if (mArraySizes[i] != arrayType.mArraySizes[i])
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+void TType::sizeUnsizedArrays(const TSpan<const unsigned int> &newArraySizes)
+{
+ ASSERT(!isArray() || mArraySizesStorage != nullptr);
+ for (size_t i = 0u; i < getNumArraySizes(); ++i)
+ {
+ if (mArraySizes[i] == 0)
+ {
+ if (i < newArraySizes.size())
+ {
+ (*mArraySizesStorage)[i] = newArraySizes[i];
+ }
+ else
+ {
+ (*mArraySizesStorage)[i] = 1u;
+ }
+ }
+ }
+ invalidateMangledName();
+}
+
+void TType::sizeOutermostUnsizedArray(unsigned int arraySize)
+{
+ ASSERT(isArray() && mArraySizesStorage != nullptr);
+ ASSERT((*mArraySizesStorage).back() == 0u);
+ (*mArraySizesStorage).back() = arraySize;
+}
+
+void TType::setBasicType(TBasicType t)
+{
+ if (type != t)
+ {
+ type = t;
+ invalidateMangledName();
+ }
+}
+
+void TType::setPrimarySize(uint8_t ps)
+{
+ if (primarySize != ps)
+ {
+ ASSERT(ps <= 4);
+ primarySize = ps;
+ invalidateMangledName();
+ }
+}
+
+void TType::setSecondarySize(uint8_t ss)
+{
+ if (secondarySize != ss)
+ {
+ ASSERT(ss <= 4);
+ secondarySize = ss;
+ invalidateMangledName();
+ }
+}
+
+void TType::makeArray(unsigned int s)
+{
+ if (mArraySizesStorage == nullptr)
+ {
+ mArraySizesStorage = new TVector<unsigned int>();
+ }
+ // Add a dimension to the current ones.
+ mArraySizesStorage->push_back(s);
+ onArrayDimensionsChange(*mArraySizesStorage);
+}
+
+void TType::makeArrays(const TSpan<const unsigned int> &sizes)
+{
+ if (mArraySizesStorage == nullptr)
+ {
+ mArraySizesStorage = new TVector<unsigned int>();
+ }
+ // Add dimensions to the current ones.
+ mArraySizesStorage->insert(mArraySizesStorage->end(), sizes.begin(), sizes.end());
+ onArrayDimensionsChange(*mArraySizesStorage);
+}
+
+void TType::setArraySize(size_t arrayDimension, unsigned int s)
+{
+ ASSERT(isArray() && mArraySizesStorage != nullptr);
+ ASSERT(arrayDimension < mArraySizesStorage->size());
+ if (mArraySizes[arrayDimension] != s)
+ {
+ (*mArraySizesStorage)[arrayDimension] = s;
+ invalidateMangledName();
+ }
+}
+
+void TType::toArrayElementType()
+{
+ ASSERT(isArray() && mArraySizesStorage != nullptr);
+ mArraySizesStorage->pop_back();
+ onArrayDimensionsChange(*mArraySizesStorage);
+}
+
+void TType::toArrayBaseType()
+{
+ if (!isArray())
+ {
+ return;
+ }
+ if (mArraySizesStorage)
+ {
+ mArraySizesStorage->clear();
+ }
+ onArrayDimensionsChange(TSpan<const unsigned int>());
+}
+
+void TType::toMatrixColumnType()
+{
+ ASSERT(isMatrix());
+ primarySize = secondarySize;
+ secondarySize = 1;
+ invalidateMangledName();
+}
+
+void TType::toComponentType()
+{
+ primarySize = 1;
+ secondarySize = 1;
+ invalidateMangledName();
+}
+
+void TType::setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn)
+{
+ if (mInterfaceBlock != interfaceBlockIn)
+ {
+ mInterfaceBlock = interfaceBlockIn;
+ invalidateMangledName();
+ }
+}
+
+void TType::setInterfaceBlockField(const TInterfaceBlock *interfaceBlockIn, size_t fieldIndex)
+{
+ setInterfaceBlock(interfaceBlockIn);
+ mInterfaceBlockFieldIndex = fieldIndex;
+}
+
+const char *TType::getMangledName() const
+{
+ if (mMangledName == nullptr)
+ {
+ mMangledName = buildMangledName();
+ }
+
+ return mMangledName;
+}
+
+void TType::realize()
+{
+ getMangledName();
+}
+
+void TType::createSamplerSymbols(const ImmutableString &namePrefix,
+ const TString &apiNamePrefix,
+ TVector<const TVariable *> *outputSymbols,
+ TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+ TSymbolTable *symbolTable) const
+{
+ if (isStructureContainingSamplers())
+ {
+ if (isArray())
+ {
+ TType elementType(*this);
+ elementType.toArrayElementType();
+ for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
+ {
+ std::stringstream elementName = sh::InitializeStream<std::stringstream>();
+ elementName << namePrefix << "_" << arrayIndex;
+ TStringStream elementApiName;
+ elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
+ elementType.createSamplerSymbols(ImmutableString(elementName.str()),
+ elementApiName.str(), outputSymbols,
+ outputSymbolsToAPINames, symbolTable);
+ }
+ }
+ else
+ {
+ mStructure->createSamplerSymbols(namePrefix.data(), apiNamePrefix, outputSymbols,
+ outputSymbolsToAPINames, symbolTable);
+ }
+ return;
+ }
+
+ ASSERT(IsSampler(type));
+ TVariable *variable =
+ new TVariable(symbolTable, namePrefix, new TType(*this), SymbolType::AngleInternal);
+ outputSymbols->push_back(variable);
+ if (outputSymbolsToAPINames)
+ {
+ (*outputSymbolsToAPINames)[variable] = apiNamePrefix;
+ }
+}
+
+TFieldListCollection::TFieldListCollection(const TFieldList *fields)
+ : mFields(fields), mObjectSize(0), mDeepestNesting(0)
+{}
+
+bool TFieldListCollection::containsArrays() const
+{
+ for (const auto *field : *mFields)
+ {
+ const TType *fieldType = field->type();
+ if (fieldType->isArray() || fieldType->isStructureContainingArrays())
+ return true;
+ }
+ return false;
+}
+
+bool TFieldListCollection::containsMatrices() const
+{
+ for (const auto *field : *mFields)
+ {
+ const TType *fieldType = field->type();
+ if (fieldType->isMatrix() || fieldType->isStructureContainingMatrices())
+ return true;
+ }
+ return false;
+}
+
+bool TFieldListCollection::containsType(TBasicType type) const
+{
+ for (const auto *field : *mFields)
+ {
+ const TType *fieldType = field->type();
+ if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
+ return true;
+ }
+ return false;
+}
+
+bool TFieldListCollection::containsSamplers() const
+{
+ for (const auto *field : *mFields)
+ {
+ const TType *fieldType = field->type();
+ if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
+ return true;
+ }
+ return false;
+}
+
+TString TFieldListCollection::buildMangledFieldList() const
+{
+ TString mangledName;
+ for (const auto *field : *mFields)
+ {
+ mangledName += field->type()->getMangledName();
+ }
+ return mangledName;
+}
+
+size_t TFieldListCollection::calculateObjectSize() const
+{
+ size_t size = 0;
+ for (const TField *field : *mFields)
+ {
+ size_t fieldSize = field->type()->getObjectSize();
+ if (fieldSize > INT_MAX - size)
+ size = INT_MAX;
+ else
+ size += fieldSize;
+ }
+ return size;
+}
+
+size_t TFieldListCollection::objectSize() const
+{
+ if (mObjectSize == 0)
+ mObjectSize = calculateObjectSize();
+ return mObjectSize;
+}
+
+int TFieldListCollection::getLocationCount() const
+{
+ int count = 0;
+ for (const TField *field : *mFields)
+ {
+ int fieldCount = field->type()->getLocationCount();
+ if (fieldCount > std::numeric_limits<int>::max() - count)
+ {
+ count = std::numeric_limits<int>::max();
+ }
+ else
+ {
+ count += fieldCount;
+ }
+ }
+ return count;
+}
+
+int TFieldListCollection::deepestNesting() const
+{
+ if (mDeepestNesting == 0)
+ mDeepestNesting = calculateDeepestNesting();
+ return mDeepestNesting;
+}
+
+const TString &TFieldListCollection::mangledFieldList() const
+{
+ if (mMangledFieldList.empty())
+ mMangledFieldList = buildMangledFieldList();
+ return mMangledFieldList;
+}
+
+int TFieldListCollection::calculateDeepestNesting() const
+{
+ int maxNesting = 0;
+ for (size_t i = 0; i < mFields->size(); ++i)
+ maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
+ return 1 + maxNesting;
+}
+
+// TPublicType implementation.
+void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
+{
+ typeSpecifierNonArray = typeSpecifier;
+ layoutQualifier = TLayoutQualifier::Create();
+ memoryQualifier = TMemoryQualifier::Create();
+ qualifier = q;
+ invariant = false;
+ precise = false;
+ precision = EbpUndefined;
+ arraySizes = nullptr;
+}
+
+void TPublicType::initializeBasicType(TBasicType basicType)
+{
+ typeSpecifierNonArray.type = basicType;
+ typeSpecifierNonArray.primarySize = 1;
+ typeSpecifierNonArray.secondarySize = 1;
+ layoutQualifier = TLayoutQualifier::Create();
+ memoryQualifier = TMemoryQualifier::Create();
+ qualifier = EvqTemporary;
+ invariant = false;
+ precise = false;
+ precision = EbpUndefined;
+ arraySizes = nullptr;
+}
+
+bool TPublicType::isStructureContainingArrays() const
+{
+ if (!typeSpecifierNonArray.userDef)
+ {
+ return false;
+ }
+
+ return typeSpecifierNonArray.userDef->containsArrays();
+}
+
+bool TPublicType::isStructureContainingType(TBasicType t) const
+{
+ if (!typeSpecifierNonArray.userDef)
+ {
+ return false;
+ }
+
+ return typeSpecifierNonArray.userDef->containsType(t);
+}
+
+void TPublicType::setArraySizes(TVector<unsigned int> *sizes)
+{
+ arraySizes = sizes;
+}
+
+bool TPublicType::isArray() const
+{
+ return arraySizes && !arraySizes->empty();
+}
+
+void TPublicType::clearArrayness()
+{
+ arraySizes = nullptr;
+}
+
+bool TPublicType::isAggregate() const
+{
+ return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Types.h b/gfx/angle/checkout/src/compiler/translator/Types.h
new file mode 100644
index 0000000000..623a3b335b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Types.h
@@ -0,0 +1,508 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TYPES_H_
+#define COMPILER_TRANSLATOR_TYPES_H_
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/SymbolUniqueId.h"
+
+namespace sh
+{
+
+struct TPublicType;
+class TType;
+class TInterfaceBlock;
+class TStructure;
+class TSymbol;
+class TVariable;
+class TIntermSymbol;
+class TSymbolTable;
+
+class TField : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TField(TType *type, const ImmutableString &name, const TSourceLoc &line, SymbolType symbolType)
+ : mType(type), mName(name), mLine(line), mSymbolType(symbolType)
+ {
+ ASSERT(mSymbolType != SymbolType::Empty);
+ }
+
+ // TODO(alokp): We should only return const type.
+ // Fix it by tweaking grammar.
+ TType *type() { return mType; }
+ const TType *type() const { return mType; }
+ const ImmutableString &name() const { return mName; }
+ const TSourceLoc &line() const { return mLine; }
+ SymbolType symbolType() const { return mSymbolType; }
+
+ private:
+ TType *mType;
+ const ImmutableString mName;
+ const TSourceLoc mLine;
+ const SymbolType mSymbolType;
+};
+
+typedef TVector<TField *> TFieldList;
+
+class TFieldListCollection : angle::NonCopyable
+{
+ public:
+ const TFieldList &fields() const { return *mFields; }
+
+ bool containsArrays() const;
+ bool containsMatrices() const;
+ bool containsType(TBasicType t) const;
+ bool containsSamplers() const;
+
+ size_t objectSize() const;
+ // How many locations the field list consumes as a uniform.
+ int getLocationCount() const;
+ int deepestNesting() const;
+ const TString &mangledFieldList() const;
+
+ protected:
+ TFieldListCollection(const TFieldList *fields);
+
+ const TFieldList *mFields;
+
+ private:
+ size_t calculateObjectSize() const;
+ int calculateDeepestNesting() const;
+ TString buildMangledFieldList() const;
+
+ mutable size_t mObjectSize;
+ mutable int mDeepestNesting;
+ mutable TString mMangledFieldList;
+};
+
+//
+// Base class for things that have a type.
+//
+class TType
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TType();
+ explicit TType(TBasicType t, uint8_t ps = 1, uint8_t ss = 1);
+ TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, uint8_t ps = 1, uint8_t ss = 1);
+ explicit TType(const TPublicType &p);
+ TType(const TStructure *userDef, bool isStructSpecifier);
+ TType(const TInterfaceBlock *interfaceBlockIn,
+ TQualifier qualifierIn,
+ TLayoutQualifier layoutQualifierIn);
+ TType(const TType &t);
+ TType &operator=(const TType &t);
+
+ constexpr TType(TBasicType t,
+ TPrecision p,
+ TQualifier q,
+ uint8_t ps,
+ uint8_t ss,
+ const TSpan<const unsigned int> arraySizes,
+ const char *mangledName)
+ : type(t),
+ precision(p),
+ qualifier(q),
+ invariant(false),
+ precise(false),
+ memoryQualifier(TMemoryQualifier::Create()),
+ layoutQualifier(TLayoutQualifier::Create()),
+ primarySize(ps),
+ secondarySize(ss),
+ mArraySizes(arraySizes),
+ mArraySizesStorage(nullptr),
+ mInterfaceBlock(nullptr),
+ mStructure(nullptr),
+ mIsStructSpecifier(false),
+ mInterfaceBlockFieldIndex(0),
+ mMangledName(mangledName)
+ {}
+
+ constexpr TType(TType &&t)
+ : type(t.type),
+ precision(t.precision),
+ qualifier(t.qualifier),
+ invariant(t.invariant),
+ precise(t.precise),
+ memoryQualifier(t.memoryQualifier),
+ layoutQualifier(t.layoutQualifier),
+ primarySize(t.primarySize),
+ secondarySize(t.secondarySize),
+ mArraySizes(t.mArraySizes),
+ mArraySizesStorage(t.mArraySizesStorage),
+ mInterfaceBlock(t.mInterfaceBlock),
+ mStructure(t.mStructure),
+ mIsStructSpecifier(t.mIsStructSpecifier),
+ mInterfaceBlockFieldIndex(0),
+ mMangledName(t.mMangledName)
+ {
+ t.mArraySizesStorage = nullptr;
+ }
+
+ constexpr TBasicType getBasicType() const { return type; }
+ void setBasicType(TBasicType t);
+
+ TPrecision getPrecision() const { return precision; }
+ void setPrecision(TPrecision p) { precision = p; }
+
+ constexpr TQualifier getQualifier() const { return qualifier; }
+ void setQualifier(TQualifier q) { qualifier = q; }
+
+ bool isInvariant() const { return invariant; }
+ void setInvariant(bool i) { invariant = i; }
+
+ bool isPrecise() const { return precise; }
+ void setPrecise(bool i) { precise = i; }
+
+ TMemoryQualifier getMemoryQualifier() const { return memoryQualifier; }
+ void setMemoryQualifier(const TMemoryQualifier &mq) { memoryQualifier = mq; }
+
+ TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; }
+ void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; }
+
+ uint8_t getNominalSize() const { return primarySize; }
+ uint8_t getSecondarySize() const { return secondarySize; }
+ uint8_t getCols() const
+ {
+ ASSERT(isMatrix());
+ return primarySize;
+ }
+ uint8_t getRows() const
+ {
+ ASSERT(isMatrix());
+ return secondarySize;
+ }
+ void setPrimarySize(uint8_t ps);
+ void setSecondarySize(uint8_t ss);
+
+ // Full size of single instance of type
+ size_t getObjectSize() const;
+
+ // Get how many locations this type consumes as a uniform.
+ int getLocationCount() const;
+
+ bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
+ bool isNonSquareMatrix() const { return isMatrix() && primarySize != secondarySize; }
+ bool isArray() const { return !mArraySizes.empty(); }
+ bool isArrayOfArrays() const { return mArraySizes.size() > 1u; }
+ size_t getNumArraySizes() const { return mArraySizes.size(); }
+ const TSpan<const unsigned int> &getArraySizes() const { return mArraySizes; }
+ unsigned int getArraySizeProduct() const;
+ bool isUnsizedArray() const;
+ unsigned int getOutermostArraySize() const
+ {
+ ASSERT(isArray());
+ return mArraySizes.back();
+ }
+ void makeArray(unsigned int s);
+
+ // sizes contain new outermost array sizes.
+ void makeArrays(const TSpan<const unsigned int> &sizes);
+ // Here, the array dimension value 0 corresponds to the innermost array.
+ void setArraySize(size_t arrayDimension, unsigned int s);
+
+ // Will set unsized array sizes according to newArraySizes. In case there are more
+ // unsized arrays than there are sizes in newArraySizes, defaults to setting any
+ // remaining array sizes to 1.
+ void sizeUnsizedArrays(const TSpan<const unsigned int> &newArraySizes);
+
+ // Will size the outermost array according to arraySize.
+ void sizeOutermostUnsizedArray(unsigned int arraySize);
+
+ // Note that the array element type might still be an array type in GLSL ES version >= 3.10.
+ void toArrayElementType();
+ // Removes all array sizes.
+ void toArrayBaseType();
+ // Turns a matrix into a column of it.
+ void toMatrixColumnType();
+ // Turns a matrix or vector into a component of it.
+ void toComponentType();
+
+ const TInterfaceBlock *getInterfaceBlock() const { return mInterfaceBlock; }
+ void setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn);
+ bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
+
+ void setInterfaceBlockField(const TInterfaceBlock *interfaceBlockIn, size_t fieldIndex);
+ size_t getInterfaceBlockFieldIndex() const { return mInterfaceBlockFieldIndex; }
+
+ bool isVector() const { return primarySize > 1 && secondarySize == 1; }
+ bool isVectorArray() const { return primarySize > 1 && secondarySize == 1 && isArray(); }
+ bool isRank0() const { return primarySize == 1 && secondarySize == 1; }
+ bool isScalar() const
+ {
+ return primarySize == 1 && secondarySize == 1 && !mStructure && !isArray();
+ }
+ bool isScalarArray() const
+ {
+ return primarySize == 1 && secondarySize == 1 && !mStructure && isArray();
+ }
+ bool isScalarFloat() const { return isScalar() && type == EbtFloat; }
+ bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }
+
+ bool canBeConstructed() const;
+
+ const TStructure *getStruct() const { return mStructure; }
+
+ static constexpr char GetSizeMangledName(uint8_t primarySize, uint8_t secondarySize)
+ {
+ unsigned int sizeKey = (secondarySize - 1u) * 4u + primarySize - 1u;
+ if (sizeKey < 10u)
+ {
+ return static_cast<char>('0' + sizeKey);
+ }
+ return static_cast<char>('A' + sizeKey - 10);
+ }
+ const char *getMangledName() const;
+
+ bool sameNonArrayType(const TType &right) const;
+
+ // Returns true if arrayType is an array made of this type.
+ bool isElementTypeOf(const TType &arrayType) const;
+
+ bool operator==(const TType &right) const
+ {
+ size_t numArraySizesL = getNumArraySizes();
+ size_t numArraySizesR = right.getNumArraySizes();
+ bool arraySizesEqual = numArraySizesL == numArraySizesR &&
+ (numArraySizesL == 0 || mArraySizes == right.mArraySizes);
+ return type == right.type && primarySize == right.primarySize &&
+ secondarySize == right.secondarySize && arraySizesEqual &&
+ mStructure == right.mStructure;
+ // don't check the qualifier, it's not ever what's being sought after
+ }
+ bool operator!=(const TType &right) const { return !operator==(right); }
+ bool operator<(const TType &right) const
+ {
+ if (type != right.type)
+ return type < right.type;
+ if (primarySize != right.primarySize)
+ return primarySize < right.primarySize;
+ if (secondarySize != right.secondarySize)
+ return secondarySize < right.secondarySize;
+ size_t numArraySizesL = getNumArraySizes();
+ size_t numArraySizesR = right.getNumArraySizes();
+ if (numArraySizesL != numArraySizesR)
+ return numArraySizesL < numArraySizesR;
+ for (size_t i = 0; i < numArraySizesL; ++i)
+ {
+ if (mArraySizes[i] != right.mArraySizes[i])
+ return mArraySizes[i] < right.mArraySizes[i];
+ }
+ if (mStructure != right.mStructure)
+ return mStructure < right.mStructure;
+
+ return false;
+ }
+
+ const char *getBasicString() const { return sh::getBasicString(type); }
+
+ const char *getPrecisionString() const { return sh::getPrecisionString(precision); }
+ const char *getQualifierString() const { return sh::getQualifierString(qualifier); }
+
+ const char *getBuiltInTypeNameString() const;
+
+ // If this type is a struct, returns the deepest struct nesting of
+ // any field in the struct. For example:
+ // struct nesting1 {
+ // vec4 position;
+ // };
+ // struct nesting2 {
+ // nesting1 field1;
+ // vec4 field2;
+ // };
+ // For type "nesting2", this method would return 2 -- the number
+ // of structures through which indirection must occur to reach the
+ // deepest field (nesting2.field1.position).
+ int getDeepestStructNesting() const;
+
+ bool isNamelessStruct() const;
+
+ bool isStructureContainingArrays() const;
+ bool isStructureContainingMatrices() const;
+ bool isStructureContainingType(TBasicType t) const;
+ bool isStructureContainingSamplers() const;
+ bool isInterfaceBlockContainingType(TBasicType t) const;
+
+ bool isStructSpecifier() const { return mIsStructSpecifier; }
+
+ // Return true if variables of this type should be replaced with an inline constant value if
+ // such is available. False will be returned in cases where output doesn't support
+ // TIntermConstantUnion nodes of the type, or if the type contains a lot of fields and creating
+ // several copies of it in the output code is undesirable for performance.
+ bool canReplaceWithConstantUnion() const;
+
+ // The char arrays passed in must be pool allocated or static.
+ void createSamplerSymbols(const ImmutableString &namePrefix,
+ const TString &apiNamePrefix,
+ TVector<const TVariable *> *outputSymbols,
+ TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+ TSymbolTable *symbolTable) const;
+
+ // Initializes all lazily-initialized members.
+ void realize();
+
+ bool isSampler() const { return IsSampler(type); }
+ bool isSamplerCube() const { return type == EbtSamplerCube; }
+ bool isAtomicCounter() const { return IsAtomicCounter(type); }
+ bool isSamplerVideoWEBGL() const { return type == EbtSamplerVideoWEBGL; }
+ bool isImage() const { return IsImage(type); }
+ bool isPixelLocal() const { return IsPixelLocal(type); }
+
+ private:
+ constexpr void invalidateMangledName() { mMangledName = nullptr; }
+ const char *buildMangledName() const;
+ constexpr void onArrayDimensionsChange(const TSpan<const unsigned int> &sizes)
+ {
+ mArraySizes = sizes;
+ invalidateMangledName();
+ }
+
+ TBasicType type;
+ TPrecision precision;
+ TQualifier qualifier;
+ bool invariant;
+ bool precise;
+
+ TMemoryQualifier memoryQualifier;
+ TLayoutQualifier layoutQualifier;
+ uint8_t primarySize; // size of vector or cols matrix
+ uint8_t secondarySize; // rows of a matrix
+
+ // Used to make an array type. Outermost array size is stored at the end of the vector. Having 0
+ // in this vector means an unsized array.
+ TSpan<const unsigned int> mArraySizes;
+ // Storage for mArraySizes, if any. This is usually the case, except for constexpr TTypes which
+ // only have a valid mArraySizes (with mArraySizesStorage being nullptr). Therefore, all
+ // modifications to array sizes happen on the storage (and if dimensions change, mArraySizes is
+ // also updated) and all reads are from mArraySizes.
+ TVector<unsigned int> *mArraySizesStorage;
+
+ // This is set only in the following two cases:
+ // 1) Represents an interface block.
+ // 2) Represents the member variable of an unnamed interface block.
+ // It's nullptr also for members of named interface blocks.
+ const TInterfaceBlock *mInterfaceBlock;
+
+ // nullptr unless this is a struct
+ const TStructure *mStructure;
+ bool mIsStructSpecifier;
+
+ // If this is a field of a nameless interface block, this would indicate which member it's
+ // refering to.
+ size_t mInterfaceBlockFieldIndex;
+
+ mutable const char *mMangledName;
+};
+
+// TTypeSpecifierNonArray stores all of the necessary fields for type_specifier_nonarray from the
+// grammar
+struct TTypeSpecifierNonArray
+{
+ TBasicType type;
+ uint8_t primarySize; // size of vector or cols of matrix
+ uint8_t secondarySize; // rows of matrix
+ const TStructure *userDef;
+ TSourceLoc line;
+
+ // true if the type was defined by a struct specifier rather than a reference to a type name.
+ bool isStructSpecifier;
+
+ void initialize(TBasicType aType, const TSourceLoc &aLine)
+ {
+ ASSERT(aType != EbtStruct);
+ type = aType;
+ primarySize = 1;
+ secondarySize = 1;
+ userDef = nullptr;
+ line = aLine;
+ isStructSpecifier = false;
+ }
+
+ void initializeStruct(const TStructure *aUserDef,
+ bool aIsStructSpecifier,
+ const TSourceLoc &aLine)
+ {
+ type = EbtStruct;
+ primarySize = 1;
+ secondarySize = 1;
+ userDef = aUserDef;
+ line = aLine;
+ isStructSpecifier = aIsStructSpecifier;
+ }
+
+ void setAggregate(uint8_t size) { primarySize = size; }
+
+ void setMatrix(uint8_t columns, uint8_t rows)
+ {
+ ASSERT(columns > 1 && rows > 1 && columns <= 4 && rows <= 4);
+ primarySize = columns;
+ secondarySize = rows;
+ }
+
+ bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
+
+ bool isVector() const { return primarySize > 1 && secondarySize == 1; }
+};
+
+//
+// This is a workaround for a problem with the yacc stack, It can't have
+// types that it thinks have non-trivial constructors. It should
+// just be used while recognizing the grammar, not anything else. Pointers
+// could be used, but also trying to avoid lots of memory management overhead.
+//
+// Not as bad as it looks, there is no actual assumption that the fields
+// match up or are name the same or anything like that.
+//
+struct TPublicType
+{
+ // Must have a trivial default constructor since it is used in YYSTYPE.
+ TPublicType() = default;
+
+ void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q);
+ void initializeBasicType(TBasicType basicType);
+
+ TBasicType getBasicType() const { return typeSpecifierNonArray.type; }
+ void setBasicType(TBasicType basicType) { typeSpecifierNonArray.type = basicType; }
+
+ uint8_t getPrimarySize() const { return typeSpecifierNonArray.primarySize; }
+ uint8_t getSecondarySize() const { return typeSpecifierNonArray.secondarySize; }
+
+ const TStructure *getUserDef() const { return typeSpecifierNonArray.userDef; }
+ const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; }
+
+ bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; }
+
+ bool isStructureContainingArrays() const;
+ bool isStructureContainingType(TBasicType t) const;
+ void setArraySizes(TVector<unsigned int> *sizes);
+ bool isArray() const;
+ void clearArrayness();
+ bool isAggregate() const;
+
+ TTypeSpecifierNonArray typeSpecifierNonArray;
+ TLayoutQualifier layoutQualifier;
+ TMemoryQualifier memoryQualifier;
+ TQualifier qualifier;
+ bool invariant;
+ bool precise;
+ TPrecision precision;
+
+ // Either nullptr or empty in case the type is not an array. The last element is the outermost
+ // array size. Note that due to bison restrictions, copies of the public type created by the
+ // copy constructor share the same arraySizes pointer.
+ const TVector<unsigned int> *arraySizes;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TYPES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp
new file mode 100644
index 0000000000..5d9a573d7b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp
@@ -0,0 +1,1223 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// UtilsHLSL.cpp:
+// Utility methods for GLSL to HLSL translation.
+//
+
+#include "compiler/translator/UtilsHLSL.h"
+
+#include "common/utilities.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/StructureHLSL.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Parameter types are only added to function names if they are ambiguous according to the
+// native HLSL compiler. Other parameter types are not added to function names to avoid
+// making function names longer.
+bool FunctionParameterNeedsDisambiguation(const TType &paramType)
+{
+ if (paramType.getObjectSize() == 4 && paramType.getBasicType() == EbtFloat)
+ {
+ // Disambiguation is needed for float2x2 and float4 parameters. These are the only
+ // built-in types that HLSL thinks are identical. float2x3 and float3x2 are different
+ // types, for example.
+ return true;
+ }
+
+ if (paramType.getBasicType() == EbtUInt || paramType.getBasicType() == EbtInt)
+ {
+ // The HLSL compiler can't always tell the difference between int and uint types when an
+ // expression is passed as a function parameter
+ return true;
+ }
+
+ if (paramType.getBasicType() == EbtStruct)
+ {
+ // Disambiguation is needed for struct parameters, since HLSL thinks that structs with
+ // the same fields but a different name are identical.
+ ASSERT(paramType.getStruct()->symbolType() != SymbolType::Empty);
+ return true;
+ }
+
+ return false;
+}
+
+void DisambiguateFunctionNameForParameterType(const TType &paramType,
+ TString *disambiguatingStringOut)
+{
+ if (FunctionParameterNeedsDisambiguation(paramType))
+ {
+ *disambiguatingStringOut += "_" + TypeString(paramType);
+ }
+}
+
+} // anonymous namespace
+
+const char *SamplerString(const TBasicType type)
+{
+ if (IsShadowSampler(type))
+ {
+ return "SamplerComparisonState";
+ }
+ else
+ {
+ return "SamplerState";
+ }
+}
+
+const char *SamplerString(HLSLTextureGroup type)
+{
+ if (type >= HLSL_COMPARISON_SAMPLER_GROUP_BEGIN && type <= HLSL_COMPARISON_SAMPLER_GROUP_END)
+ {
+ return "SamplerComparisonState";
+ }
+ else
+ {
+ return "SamplerState";
+ }
+}
+
+HLSLTextureGroup TextureGroup(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+
+{
+ switch (type)
+ {
+ case EbtSampler2D:
+ case EbtSamplerVideoWEBGL:
+ return HLSL_TEXTURE_2D;
+ case EbtSamplerCube:
+ return HLSL_TEXTURE_CUBE;
+ case EbtSamplerExternalOES:
+ return HLSL_TEXTURE_2D;
+ case EbtSampler2DArray:
+ return HLSL_TEXTURE_2D_ARRAY;
+ case EbtSampler3D:
+ return HLSL_TEXTURE_3D;
+ case EbtSampler2DMS:
+ return HLSL_TEXTURE_2D_MS;
+ case EbtSampler2DMSArray:
+ return HLSL_TEXTURE_2D_MS_ARRAY;
+ case EbtSamplerBuffer:
+ return HLSL_TEXTURE_BUFFER;
+ case EbtISampler2D:
+ return HLSL_TEXTURE_2D_INT4;
+ case EbtISamplerBuffer:
+ return HLSL_TEXTURE_BUFFER_INT4;
+ case EbtISampler3D:
+ return HLSL_TEXTURE_3D_INT4;
+ case EbtISamplerCube:
+ return HLSL_TEXTURE_2D_ARRAY_INT4;
+ case EbtISampler2DArray:
+ return HLSL_TEXTURE_2D_ARRAY_INT4;
+ case EbtISampler2DMS:
+ return HLSL_TEXTURE_2D_MS_INT4;
+ case EbtISampler2DMSArray:
+ return HLSL_TEXTURE_2D_MS_ARRAY_INT4;
+ case EbtUSampler2D:
+ return HLSL_TEXTURE_2D_UINT4;
+ case EbtUSampler3D:
+ return HLSL_TEXTURE_3D_UINT4;
+ case EbtUSamplerCube:
+ return HLSL_TEXTURE_2D_ARRAY_UINT4;
+ case EbtUSamplerBuffer:
+ return HLSL_TEXTURE_BUFFER_UINT4;
+ case EbtUSampler2DArray:
+ return HLSL_TEXTURE_2D_ARRAY_UINT4;
+ case EbtUSampler2DMS:
+ return HLSL_TEXTURE_2D_MS_UINT4;
+ case EbtUSampler2DMSArray:
+ return HLSL_TEXTURE_2D_MS_ARRAY_UINT4;
+ case EbtSampler2DShadow:
+ return HLSL_TEXTURE_2D_COMPARISON;
+ case EbtSamplerCubeShadow:
+ return HLSL_TEXTURE_CUBE_COMPARISON;
+ case EbtSampler2DArrayShadow:
+ return HLSL_TEXTURE_2D_ARRAY_COMPARISON;
+ case EbtImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_TEXTURE_2D;
+ case EiifRGBA8:
+ return HLSL_TEXTURE_2D_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_TEXTURE_2D_SNORM;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtIImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_TEXTURE_2D_INT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtUImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_TEXTURE_2D_UINT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_TEXTURE_3D;
+ case EiifRGBA8:
+ return HLSL_TEXTURE_3D_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_TEXTURE_3D_SNORM;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtIImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_TEXTURE_3D_INT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtUImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_TEXTURE_3D_UINT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtImage2DArray:
+ case EbtImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_TEXTURE_2D_ARRAY;
+ case EiifRGBA8:
+ return HLSL_TEXTURE_2D_ARRAY_UNORN;
+ case EiifRGBA8_SNORM:
+ return HLSL_TEXTURE_2D_ARRAY_SNORM;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtIImage2DArray:
+ case EbtIImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_TEXTURE_2D_ARRAY_INT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtUImage2DArray:
+ case EbtUImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_TEXTURE_2D_ARRAY_UINT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_TEXTURE_BUFFER;
+ case EiifRGBA8:
+ return HLSL_TEXTURE_BUFFER_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_TEXTURE_BUFFER_SNORM;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtUImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_TEXTURE_BUFFER_UINT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtIImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_TEXTURE_BUFFER_INT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+}
+
+const char *TextureString(const HLSLTextureGroup textureGroup)
+{
+ switch (textureGroup)
+ {
+ case HLSL_TEXTURE_2D:
+ return "Texture2D<float4>";
+ case HLSL_TEXTURE_CUBE:
+ return "TextureCube<float4>";
+ case HLSL_TEXTURE_2D_ARRAY:
+ return "Texture2DArray<float4>";
+ case HLSL_TEXTURE_3D:
+ return "Texture3D<float4>";
+ case HLSL_TEXTURE_2D_UNORM:
+ return "Texture2D<unorm float4>";
+ case HLSL_TEXTURE_CUBE_UNORM:
+ return "TextureCube<unorm float4>";
+ case HLSL_TEXTURE_2D_ARRAY_UNORN:
+ return "Texture2DArray<unorm float4>";
+ case HLSL_TEXTURE_3D_UNORM:
+ return "Texture3D<unorm float4>";
+ case HLSL_TEXTURE_2D_SNORM:
+ return "Texture2D<snorm float4>";
+ case HLSL_TEXTURE_CUBE_SNORM:
+ return "TextureCube<snorm float4>";
+ case HLSL_TEXTURE_2D_ARRAY_SNORM:
+ return "Texture2DArray<snorm float4>";
+ case HLSL_TEXTURE_3D_SNORM:
+ return "Texture3D<snorm float4>";
+ case HLSL_TEXTURE_2D_MS:
+ return "Texture2DMS<float4>";
+ case HLSL_TEXTURE_2D_MS_ARRAY:
+ return "Texture2DMSArray<float4>";
+ case HLSL_TEXTURE_2D_INT4:
+ return "Texture2D<int4>";
+ case HLSL_TEXTURE_3D_INT4:
+ return "Texture3D<int4>";
+ case HLSL_TEXTURE_2D_ARRAY_INT4:
+ return "Texture2DArray<int4>";
+ case HLSL_TEXTURE_2D_MS_INT4:
+ return "Texture2DMS<int4>";
+ case HLSL_TEXTURE_2D_MS_ARRAY_INT4:
+ return "Texture2DMSArray<int4>";
+ case HLSL_TEXTURE_2D_UINT4:
+ return "Texture2D<uint4>";
+ case HLSL_TEXTURE_3D_UINT4:
+ return "Texture3D<uint4>";
+ case HLSL_TEXTURE_2D_ARRAY_UINT4:
+ return "Texture2DArray<uint4>";
+ case HLSL_TEXTURE_2D_MS_UINT4:
+ return "Texture2DMS<uint4>";
+ case HLSL_TEXTURE_2D_MS_ARRAY_UINT4:
+ return "Texture2DMSArray<uint4>";
+ case HLSL_TEXTURE_2D_COMPARISON:
+ return "Texture2D";
+ case HLSL_TEXTURE_CUBE_COMPARISON:
+ return "TextureCube";
+ case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
+ return "Texture2DArray";
+ case HLSL_TEXTURE_BUFFER:
+ return "Buffer<float4>";
+ case HLSL_TEXTURE_BUFFER_INT4:
+ return "Buffer<int4>";
+ case HLSL_TEXTURE_BUFFER_UINT4:
+ return "Buffer<uint4>";
+ case HLSL_TEXTURE_BUFFER_UNORM:
+ return "Buffer<unorm float4>";
+ case HLSL_TEXTURE_BUFFER_SNORM:
+ return "Buffer<snorm float4>";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown read texture type>";
+}
+
+const char *TextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+{
+ return TextureString(TextureGroup(type, imageInternalFormat));
+}
+
+const char *TextureGroupSuffix(const HLSLTextureGroup type)
+{
+ switch (type)
+ {
+ case HLSL_TEXTURE_2D:
+ return "2D";
+ case HLSL_TEXTURE_CUBE:
+ return "Cube";
+ case HLSL_TEXTURE_2D_ARRAY:
+ return "2DArray";
+ case HLSL_TEXTURE_3D:
+ return "3D";
+ case HLSL_TEXTURE_2D_UNORM:
+ return "2D_unorm_float4_";
+ case HLSL_TEXTURE_CUBE_UNORM:
+ return "Cube_unorm_float4_";
+ case HLSL_TEXTURE_2D_ARRAY_UNORN:
+ return "2DArray_unorm_float4_";
+ case HLSL_TEXTURE_3D_UNORM:
+ return "3D_unorm_float4_";
+ case HLSL_TEXTURE_2D_SNORM:
+ return "2D_snorm_float4_";
+ case HLSL_TEXTURE_CUBE_SNORM:
+ return "Cube_snorm_float4_";
+ case HLSL_TEXTURE_2D_ARRAY_SNORM:
+ return "2DArray_snorm_float4_";
+ case HLSL_TEXTURE_3D_SNORM:
+ return "3D_snorm_float4_";
+ case HLSL_TEXTURE_2D_MS:
+ return "2DMS";
+ case HLSL_TEXTURE_2D_MS_ARRAY:
+ return "2DMSArray";
+ case HLSL_TEXTURE_2D_INT4:
+ return "2D_int4_";
+ case HLSL_TEXTURE_3D_INT4:
+ return "3D_int4_";
+ case HLSL_TEXTURE_2D_ARRAY_INT4:
+ return "2DArray_int4_";
+ case HLSL_TEXTURE_2D_MS_INT4:
+ return "2DMS_int4_";
+ case HLSL_TEXTURE_2D_MS_ARRAY_INT4:
+ return "2DMSArray_int4_";
+ case HLSL_TEXTURE_2D_UINT4:
+ return "2D_uint4_";
+ case HLSL_TEXTURE_3D_UINT4:
+ return "3D_uint4_";
+ case HLSL_TEXTURE_2D_ARRAY_UINT4:
+ return "2DArray_uint4_";
+ case HLSL_TEXTURE_2D_MS_UINT4:
+ return "2DMS_uint4_";
+ case HLSL_TEXTURE_2D_MS_ARRAY_UINT4:
+ return "2DMSArray_uint4_";
+ case HLSL_TEXTURE_2D_COMPARISON:
+ return "2D_comparison";
+ case HLSL_TEXTURE_CUBE_COMPARISON:
+ return "Cube_comparison";
+ case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
+ return "2DArray_comparison";
+ case HLSL_TEXTURE_BUFFER:
+ return "Buffer";
+ case HLSL_TEXTURE_BUFFER_INT4:
+ return "Buffer_int4_";
+ case HLSL_TEXTURE_BUFFER_UINT4:
+ return "Buffer_uint4_";
+ case HLSL_TEXTURE_BUFFER_UNORM:
+ return "Buffer_unorm_float4_";
+ case HLSL_TEXTURE_BUFFER_SNORM:
+ return "Buffer_snorm_float4_";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown texture type>";
+}
+
+const char *TextureGroupSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat)
+{
+ return TextureGroupSuffix(TextureGroup(type, imageInternalFormat));
+}
+
+const char *TextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+{
+ switch (type)
+ {
+ case EbtISamplerCube:
+ return "Cube_int4_";
+ case EbtUSamplerCube:
+ return "Cube_uint4_";
+ case EbtSamplerExternalOES:
+ return "_External";
+ case EbtImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return "Cube_float4_";
+ case EiifRGBA8:
+ return "Cube_unorm_float4_";
+ case EiifRGBA8_SNORM:
+ return "Cube_snorm_float4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return "Cube_int4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return "Cube_uint4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ default:
+ // All other types are identified by their group suffix
+ return TextureGroupSuffix(type, imageInternalFormat);
+ }
+ UNREACHABLE();
+ return "_TTS_invalid_";
+}
+
+HLSLRWTextureGroup RWTextureGroup(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat)
+
+{
+ switch (type)
+ {
+ case EbtImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_RWTEXTURE_2D_FLOAT4;
+ case EiifRGBA8:
+ return HLSL_RWTEXTURE_2D_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_RWTEXTURE_2D_SNORM;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_RWTEXTURE_2D_INT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_RWTEXTURE_2D_UINT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_RWTEXTURE_3D_FLOAT4;
+ case EiifRGBA8:
+ return HLSL_RWTEXTURE_3D_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_RWTEXTURE_3D_SNORM;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_RWTEXTURE_3D_INT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_RWTEXTURE_3D_UINT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtImage2DArray:
+ case EbtImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_RWTEXTURE_2D_ARRAY_FLOAT4;
+ case EiifRGBA8:
+ return HLSL_RWTEXTURE_2D_ARRAY_UNORN;
+ case EiifRGBA8_SNORM:
+ return HLSL_RWTEXTURE_2D_ARRAY_SNORM;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImage2DArray:
+ case EbtIImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_RWTEXTURE_2D_ARRAY_INT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImage2DArray:
+ case EbtUImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_RWTEXTURE_2D_ARRAY_UINT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_RWTEXTURE_BUFFER_FLOAT4;
+ case EiifRGBA8:
+ return HLSL_RWTEXTURE_BUFFER_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_RWTEXTURE_BUFFER_SNORM;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_RWTEXTURE_BUFFER_INT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_RWTEXTURE_BUFFER_UINT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ return HLSL_RWTEXTURE_UNKNOWN;
+}
+
+const char *RWTextureString(const HLSLRWTextureGroup RWTextureGroup)
+{
+ switch (RWTextureGroup)
+ {
+ case HLSL_RWTEXTURE_2D_FLOAT4:
+ return "RWTexture2D<float4>";
+ case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4:
+ return "RWTexture2DArray<float4>";
+ case HLSL_RWTEXTURE_3D_FLOAT4:
+ return "RWTexture3D<float4>";
+ case HLSL_RWTEXTURE_2D_UNORM:
+ return "RWTexture2D<unorm float4>";
+ case HLSL_RWTEXTURE_2D_ARRAY_UNORN:
+ return "RWTexture2DArray<unorm float4>";
+ case HLSL_RWTEXTURE_3D_UNORM:
+ return "RWTexture3D<unorm float4>";
+ case HLSL_RWTEXTURE_2D_SNORM:
+ return "RWTexture2D<snorm float4>";
+ case HLSL_RWTEXTURE_2D_ARRAY_SNORM:
+ return "RWTexture2DArray<snorm float4>";
+ case HLSL_RWTEXTURE_3D_SNORM:
+ return "RWTexture3D<snorm float4>";
+ case HLSL_RWTEXTURE_2D_UINT4:
+ return "RWTexture2D<uint4>";
+ case HLSL_RWTEXTURE_2D_ARRAY_UINT4:
+ return "RWTexture2DArray<uint4>";
+ case HLSL_RWTEXTURE_3D_UINT4:
+ return "RWTexture3D<uint4>";
+ case HLSL_RWTEXTURE_2D_INT4:
+ return "RWTexture2D<int4>";
+ case HLSL_RWTEXTURE_2D_ARRAY_INT4:
+ return "RWTexture2DArray<int4>";
+ case HLSL_RWTEXTURE_3D_INT4:
+ return "RWTexture3D<int4>";
+ case HLSL_RWTEXTURE_BUFFER_FLOAT4:
+ return "RWBuffer<float4>";
+ case HLSL_RWTEXTURE_BUFFER_UNORM:
+ return "RWBuffer<unorm float4>";
+ case HLSL_RWTEXTURE_BUFFER_SNORM:
+ return "RWBuffer<snorm float4>";
+ case HLSL_RWTEXTURE_BUFFER_UINT4:
+ return "RWBuffer<uint4>";
+ case HLSL_RWTEXTURE_BUFFER_INT4:
+ return "RWBuffer<int4>";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown read and write texture type>";
+}
+
+const char *RWTextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+{
+ return RWTextureString(RWTextureGroup(type, imageInternalFormat));
+}
+
+const char *RWTextureGroupSuffix(const HLSLRWTextureGroup type)
+{
+ switch (type)
+ {
+ case HLSL_RWTEXTURE_2D_FLOAT4:
+ return "RW2D_float4_";
+ case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4:
+ return "RW2DArray_float4_";
+ case HLSL_RWTEXTURE_3D_FLOAT4:
+ return "RW3D_float4_";
+ case HLSL_RWTEXTURE_2D_UNORM:
+ return "RW2D_unorm_float4_";
+ case HLSL_RWTEXTURE_2D_ARRAY_UNORN:
+ return "RW2DArray_unorm_float4_";
+ case HLSL_RWTEXTURE_3D_UNORM:
+ return "RW3D_unorm_float4_";
+ case HLSL_RWTEXTURE_2D_SNORM:
+ return "RW2D_snorm_float4_";
+ case HLSL_RWTEXTURE_2D_ARRAY_SNORM:
+ return "RW2DArray_snorm_float4_";
+ case HLSL_RWTEXTURE_3D_SNORM:
+ return "RW3D_snorm_float4_";
+ case HLSL_RWTEXTURE_2D_UINT4:
+ return "RW2D_uint4_";
+ case HLSL_RWTEXTURE_2D_ARRAY_UINT4:
+ return "RW2DArray_uint4_";
+ case HLSL_RWTEXTURE_3D_UINT4:
+ return "RW3D_uint4_";
+ case HLSL_RWTEXTURE_2D_INT4:
+ return "RW2D_int4_";
+ case HLSL_RWTEXTURE_2D_ARRAY_INT4:
+ return "RW2DArray_int4_";
+ case HLSL_RWTEXTURE_3D_INT4:
+ return "RW3D_int4_";
+ case HLSL_RWTEXTURE_BUFFER_FLOAT4:
+ return "RWBuffer_float4_";
+ case HLSL_RWTEXTURE_BUFFER_UNORM:
+ return "RWBuffer_unorm_float4_";
+ case HLSL_RWTEXTURE_BUFFER_SNORM:
+ return "RWBuffer_snorm_float4_";
+ case HLSL_RWTEXTURE_BUFFER_UINT4:
+ return "RWBuffer_uint4_";
+ case HLSL_RWTEXTURE_BUFFER_INT4:
+ return "RWBuffer_int4_";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown read and write resource>";
+}
+
+const char *RWTextureGroupSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat)
+{
+ return RWTextureGroupSuffix(RWTextureGroup(type, imageInternalFormat));
+}
+
+const char *RWTextureTypeSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat)
+{
+ switch (type)
+ {
+ case EbtImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return "RWCube_float4_";
+ case EiifRGBA8:
+ return "RWCube_unorm_float4_";
+ case EiifRGBA8_SNORM:
+ return "RWCube_unorm_float4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return "RWCube_int4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return "RWCube_uint4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ default:
+ // All other types are identified by their group suffix
+ return RWTextureGroupSuffix(type, imageInternalFormat);
+ }
+ UNREACHABLE();
+ return "_RWTS_invalid_";
+}
+
+TString DecorateField(const ImmutableString &string, const TStructure &structure)
+{
+ if (structure.symbolType() != SymbolType::BuiltIn)
+ {
+ return Decorate(string);
+ }
+
+ return TString(string.data());
+}
+
+TString DecoratePrivate(const ImmutableString &privateText)
+{
+ return "dx_" + TString(privateText.data());
+}
+
+TString Decorate(const ImmutableString &string)
+{
+ if (!gl::IsBuiltInName(string.data()))
+ {
+ return "_" + TString(string.data());
+ }
+
+ return TString(string.data());
+}
+
+TString DecorateVariableIfNeeded(const TVariable &variable)
+{
+ if (variable.symbolType() == SymbolType::AngleInternal ||
+ variable.symbolType() == SymbolType::BuiltIn || variable.symbolType() == SymbolType::Empty)
+ {
+ // Besides handling internal variables, we generate names for nameless parameters here.
+ const ImmutableString &name = variable.name();
+ // The name should not have a prefix reserved for user-defined variables or functions.
+ ASSERT(!name.beginsWith("f_"));
+ ASSERT(!name.beginsWith("_"));
+ return TString(name.data());
+ }
+ // For user defined variables, combine variable name with unique id
+ // so variables of the same name in different scopes do not get overwritten.
+ else if (variable.symbolType() == SymbolType::UserDefined &&
+ variable.getType().getQualifier() == EvqTemporary)
+ {
+ return Decorate(variable.name()) + str(variable.uniqueId().get());
+ }
+ else
+ {
+ return Decorate(variable.name());
+ }
+}
+
+TString DecorateFunctionIfNeeded(const TFunction *func)
+{
+ if (func->symbolType() == SymbolType::AngleInternal)
+ {
+ // The name should not have a prefix reserved for user-defined variables or functions.
+ ASSERT(!func->name().beginsWith("f_"));
+ ASSERT(!func->name().beginsWith("_"));
+ return TString(func->name().data());
+ }
+ ASSERT(!gl::IsBuiltInName(func->name().data()));
+ // Add an additional f prefix to functions so that they're always disambiguated from variables.
+ // This is necessary in the corner case where a variable declaration hides a function that it
+ // uses in its initializer.
+ return "f_" + TString(func->name().data());
+}
+
+TString TypeString(const TType &type)
+{
+ const TStructure *structure = type.getStruct();
+ if (structure)
+ {
+ if (structure->symbolType() != SymbolType::Empty)
+ {
+ return StructNameString(*structure);
+ }
+ else // Nameless structure, define in place
+ {
+ return StructureHLSL::defineNameless(*structure);
+ }
+ }
+ else if (type.isMatrix())
+ {
+ uint8_t cols = type.getCols();
+ uint8_t rows = type.getRows();
+ return "float" + str(cols) + "x" + str(rows);
+ }
+ else
+ {
+ switch (type.getBasicType())
+ {
+ case EbtFloat:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "float";
+ case 2:
+ return "float2";
+ case 3:
+ return "float3";
+ case 4:
+ return "float4";
+ }
+ case EbtInt:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "int";
+ case 2:
+ return "int2";
+ case 3:
+ return "int3";
+ case 4:
+ return "int4";
+ }
+ case EbtUInt:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "uint";
+ case 2:
+ return "uint2";
+ case 3:
+ return "uint3";
+ case 4:
+ return "uint4";
+ }
+ case EbtBool:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "bool";
+ case 2:
+ return "bool2";
+ case 3:
+ return "bool3";
+ case 4:
+ return "bool4";
+ }
+ case EbtVoid:
+ return "void";
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ return "sampler2D";
+ case EbtSamplerCube:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ return "samplerCUBE";
+ case EbtSamplerExternalOES:
+ return "sampler2D";
+ case EbtSamplerVideoWEBGL:
+ return "sampler2D";
+ case EbtAtomicCounter:
+ // Multiple atomic_uints will be implemented as a single RWByteAddressBuffer
+ return "RWByteAddressBuffer";
+ default:
+ break;
+ }
+ }
+
+ UNREACHABLE();
+ return "<unknown type>";
+}
+
+TString StructNameString(const TStructure &structure)
+{
+ if (structure.symbolType() == SymbolType::Empty)
+ {
+ return "";
+ }
+
+ // For structures at global scope we use a consistent
+ // translation so that we can link between shader stages.
+ if (structure.atGlobalScope())
+ {
+ return Decorate(structure.name());
+ }
+
+ return "ss" + str(structure.uniqueId().get()) + "_" + TString(structure.name().data());
+}
+
+TString QualifiedStructNameString(const TStructure &structure,
+ bool useHLSLRowMajorPacking,
+ bool useStd140Packing,
+ bool forcePadding)
+{
+ if (structure.symbolType() == SymbolType::Empty)
+ {
+ return "";
+ }
+
+ TString prefix = "";
+
+ // Structs packed with row-major matrices in HLSL are prefixed with "rm"
+ // GLSL column-major maps to HLSL row-major, and the converse is true
+
+ if (useStd140Packing)
+ {
+ prefix += "std_";
+ }
+
+ if (useHLSLRowMajorPacking)
+ {
+ prefix += "rm_";
+ }
+
+ if (forcePadding)
+ {
+ prefix += "fp_";
+ }
+
+ return prefix + StructNameString(structure);
+}
+
+const char *InterpolationString(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqVaryingIn:
+ return "";
+ case EvqFragmentIn:
+ return "";
+ case EvqSmoothIn:
+ return "linear";
+ case EvqFlatIn:
+ return "nointerpolation";
+ case EvqCentroidIn:
+ return "centroid";
+ case EvqVaryingOut:
+ return "";
+ case EvqVertexOut:
+ return "";
+ case EvqSmoothOut:
+ return "linear";
+ case EvqFlatOut:
+ return "nointerpolation";
+ case EvqCentroidOut:
+ return "centroid";
+ case EvqSampleIn:
+ return "sample";
+ default:
+ UNREACHABLE();
+ }
+
+ return "";
+}
+
+const char *QualifierString(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqParamIn:
+ return "in";
+ case EvqParamOut:
+ return "inout"; // 'out' results in an HLSL error if not all fields are written, for
+ // GLSL it's undefined
+ case EvqParamInOut:
+ return "inout";
+ case EvqParamConst:
+ return "const";
+ case EvqSampleOut:
+ return "sample";
+ default:
+ UNREACHABLE();
+ }
+
+ return "";
+}
+
+TString DisambiguateFunctionName(const TFunction *func)
+{
+ TString disambiguatingString;
+ size_t paramCount = func->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ DisambiguateFunctionNameForParameterType(func->getParam(i)->getType(),
+ &disambiguatingString);
+ }
+ return disambiguatingString;
+}
+
+TString DisambiguateFunctionName(const TIntermSequence *args)
+{
+ TString disambiguatingString;
+ for (TIntermNode *arg : *args)
+ {
+ ASSERT(arg->getAsTyped());
+ DisambiguateFunctionNameForParameterType(arg->getAsTyped()->getType(),
+ &disambiguatingString);
+ }
+ return disambiguatingString;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h
new file mode 100644
index 0000000000..722b61f3ca
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h
@@ -0,0 +1,148 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// UtilsHLSL.h:
+// Utility methods for GLSL to HLSL translation.
+//
+
+#ifndef COMPILER_TRANSLATOR_UTILSHLSL_H_
+#define COMPILER_TRANSLATOR_UTILSHLSL_H_
+
+#include <vector>
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Types.h"
+
+#include "angle_gl.h"
+
+namespace sh
+{
+
+class TFunction;
+
+// HLSL Texture type for GLSL sampler type and readonly image type.
+enum HLSLTextureGroup
+{
+ // read resources
+ HLSL_TEXTURE_2D,
+ HLSL_TEXTURE_MIN = HLSL_TEXTURE_2D,
+
+ HLSL_TEXTURE_CUBE,
+ HLSL_TEXTURE_2D_ARRAY,
+ HLSL_TEXTURE_3D,
+ HLSL_TEXTURE_2D_UNORM,
+ HLSL_TEXTURE_CUBE_UNORM,
+ HLSL_TEXTURE_2D_ARRAY_UNORN,
+ HLSL_TEXTURE_3D_UNORM,
+ HLSL_TEXTURE_2D_SNORM,
+ HLSL_TEXTURE_CUBE_SNORM,
+ HLSL_TEXTURE_2D_ARRAY_SNORM,
+ HLSL_TEXTURE_3D_SNORM,
+ HLSL_TEXTURE_2D_MS,
+ HLSL_TEXTURE_2D_MS_ARRAY,
+ HLSL_TEXTURE_2D_INT4,
+ HLSL_TEXTURE_3D_INT4,
+ HLSL_TEXTURE_2D_ARRAY_INT4,
+ HLSL_TEXTURE_2D_MS_INT4,
+ HLSL_TEXTURE_2D_MS_ARRAY_INT4,
+ HLSL_TEXTURE_2D_UINT4,
+ HLSL_TEXTURE_3D_UINT4,
+ HLSL_TEXTURE_2D_ARRAY_UINT4,
+ HLSL_TEXTURE_2D_MS_UINT4,
+ HLSL_TEXTURE_2D_MS_ARRAY_UINT4,
+
+ HLSL_TEXTURE_BUFFER,
+ HLSL_TEXTURE_BUFFER_UNORM,
+ HLSL_TEXTURE_BUFFER_SNORM,
+ HLSL_TEXTURE_BUFFER_UINT4,
+ HLSL_TEXTURE_BUFFER_INT4,
+
+ // Comparison samplers
+
+ HLSL_TEXTURE_2D_COMPARISON,
+ HLSL_TEXTURE_CUBE_COMPARISON,
+ HLSL_TEXTURE_2D_ARRAY_COMPARISON,
+
+ HLSL_COMPARISON_SAMPLER_GROUP_BEGIN = HLSL_TEXTURE_2D_COMPARISON,
+ HLSL_COMPARISON_SAMPLER_GROUP_END = HLSL_TEXTURE_2D_ARRAY_COMPARISON,
+
+ HLSL_TEXTURE_UNKNOWN,
+ HLSL_TEXTURE_MAX = HLSL_TEXTURE_UNKNOWN
+};
+
+// HLSL RWTexture type for GLSL read and write image type.
+enum HLSLRWTextureGroup
+{
+ // read/write resource
+ HLSL_RWTEXTURE_2D_FLOAT4,
+ HLSL_RWTEXTURE_MIN = HLSL_RWTEXTURE_2D_FLOAT4,
+ HLSL_RWTEXTURE_2D_ARRAY_FLOAT4,
+ HLSL_RWTEXTURE_3D_FLOAT4,
+ HLSL_RWTEXTURE_2D_UNORM,
+ HLSL_RWTEXTURE_2D_ARRAY_UNORN,
+ HLSL_RWTEXTURE_3D_UNORM,
+ HLSL_RWTEXTURE_2D_SNORM,
+ HLSL_RWTEXTURE_2D_ARRAY_SNORM,
+ HLSL_RWTEXTURE_3D_SNORM,
+ HLSL_RWTEXTURE_2D_UINT4,
+ HLSL_RWTEXTURE_2D_ARRAY_UINT4,
+ HLSL_RWTEXTURE_3D_UINT4,
+ HLSL_RWTEXTURE_2D_INT4,
+ HLSL_RWTEXTURE_2D_ARRAY_INT4,
+ HLSL_RWTEXTURE_3D_INT4,
+
+ HLSL_RWTEXTURE_BUFFER_FLOAT4,
+ HLSL_RWTEXTURE_BUFFER_UNORM,
+ HLSL_RWTEXTURE_BUFFER_SNORM,
+ HLSL_RWTEXTURE_BUFFER_UINT4,
+ HLSL_RWTEXTURE_BUFFER_INT4,
+
+ HLSL_RWTEXTURE_UNKNOWN,
+ HLSL_RWTEXTURE_MAX = HLSL_RWTEXTURE_UNKNOWN
+};
+
+HLSLTextureGroup TextureGroup(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+const char *TextureString(const HLSLTextureGroup textureGroup);
+const char *TextureString(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+const char *TextureGroupSuffix(const HLSLTextureGroup type);
+const char *TextureGroupSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+const char *TextureTypeSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+HLSLRWTextureGroup RWTextureGroup(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat);
+const char *RWTextureString(const HLSLRWTextureGroup textureGroup);
+const char *RWTextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat);
+const char *RWTextureGroupSuffix(const HLSLRWTextureGroup type);
+const char *RWTextureGroupSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat);
+const char *RWTextureTypeSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat);
+
+const char *SamplerString(const TBasicType type);
+const char *SamplerString(HLSLTextureGroup type);
+
+// Adds a prefix to user-defined names to avoid naming clashes.
+TString Decorate(const ImmutableString &string);
+TString DecorateVariableIfNeeded(const TVariable &variable);
+TString DecorateFunctionIfNeeded(const TFunction *func);
+TString DecorateField(const ImmutableString &string, const TStructure &structure);
+TString DecoratePrivate(const ImmutableString &privateText);
+TString TypeString(const TType &type);
+TString StructNameString(const TStructure &structure);
+TString QualifiedStructNameString(const TStructure &structure,
+ bool useHLSLRowMajorPacking,
+ bool useStd140Packing,
+ bool forcePackingEnd);
+const char *InterpolationString(TQualifier qualifier);
+const char *QualifierString(TQualifier qualifier);
+// Parameters may need to be included in function names to disambiguate between overloaded
+// functions.
+TString DisambiguateFunctionName(const TFunction *func);
+TString DisambiguateFunctionName(const TIntermSequence *args);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_UTILSHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateAST.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateAST.cpp
new file mode 100644
index 0000000000..faba9a9a82
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateAST.cpp
@@ -0,0 +1,1133 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/ValidateAST.h"
+
+#include "common/utilities.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/SpecializationConstant.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class ValidateAST : public TIntermTraverser
+{
+ public:
+ static bool validate(TIntermNode *root,
+ TDiagnostics *diagnostics,
+ const ValidateASTOptions &options);
+
+ void visitSymbol(TIntermSymbol *node) override;
+ void visitConstantUnion(TIntermConstantUnion *node) override;
+ bool visitSwizzle(Visit visit, TIntermSwizzle *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+ bool visitTernary(Visit visit, TIntermTernary *node) override;
+ bool visitIfElse(Visit visit, TIntermIfElse *node) override;
+ bool visitSwitch(Visit visit, TIntermSwitch *node) override;
+ bool visitCase(Visit visit, TIntermCase *node) override;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitLoop(Visit visit, TIntermLoop *node) override;
+ bool visitBranch(Visit visit, TIntermBranch *node) override;
+ void visitPreprocessorDirective(TIntermPreprocessorDirective *node) override;
+
+ private:
+ ValidateAST(TIntermNode *root, TDiagnostics *diagnostics, const ValidateASTOptions &options);
+
+ // Visit as a generic node
+ void visitNode(Visit visit, TIntermNode *node);
+ // Visit a structure or interface block, and recursively visit its fields of structure type.
+ void visitStructOrInterfaceBlockDeclaration(const TType &type, const TSourceLoc &location);
+ void visitStructUsage(const TType &type, const TSourceLoc &location);
+ // Visit a unary or aggregate node and validate its built-in op against its built-in function.
+ void visitBuiltInFunction(TIntermOperator *op, const TFunction *function);
+ // Visit an aggregate node and validate its function call is to one that's already defined.
+ void visitFunctionCall(TIntermAggregate *node);
+ // Visit a binary node and validate its type against its operands.
+ void validateExpressionTypeBinary(TIntermBinary *node);
+ // Visit a switch node and validate its selector type is integer.
+ void validateExpressionTypeSwitch(TIntermSwitch *node);
+ // Visit a symbol node and validate it's declared previously.
+ void visitVariableNeedingDeclaration(TIntermSymbol *node);
+ // Visit a built-in symbol node and validate it's consistently used across the tree.
+ void visitBuiltInVariable(TIntermSymbol *node);
+
+ void scope(Visit visit);
+ bool isVariableDeclared(const TVariable *variable);
+ bool variableNeedsDeclaration(const TVariable *variable);
+ const TFieldListCollection *getStructOrInterfaceBlock(const TType &type,
+ ImmutableString *typeNameOut);
+
+ void expectNonNullChildren(Visit visit, TIntermNode *node, size_t least_count);
+
+ bool validateInternal();
+
+ ValidateASTOptions mOptions;
+ TDiagnostics *mDiagnostics;
+
+ // For validateSingleParent:
+ std::map<TIntermNode *, TIntermNode *> mParent;
+ bool mSingleParentFailed = false;
+
+ // For validateVariableReferences:
+ std::vector<std::set<const TVariable *>> mDeclaredVariables;
+ std::set<const TInterfaceBlock *> mNamelessInterfaceBlocks;
+ std::map<ImmutableString, const TVariable *> mReferencedBuiltIns;
+ bool mVariableReferencesFailed = false;
+
+ // For validateBuiltInOps:
+ bool mBuiltInOpsFailed = false;
+
+ // For validateFunctionCall:
+ std::set<const TFunction *> mDeclaredFunctions;
+ bool mFunctionCallFailed = false;
+
+ // For validateNoRawFunctionCalls:
+ bool mNoRawFunctionCallsFailed = false;
+
+ // For validateNullNodes:
+ bool mNullNodesFailed = false;
+
+ // For validateQualifiers:
+ bool mQualifiersFailed = false;
+
+ // For validatePrecision:
+ bool mPrecisionFailed = false;
+
+ // For validateStructUsage:
+ std::vector<std::map<ImmutableString, const TFieldListCollection *>> mStructsAndBlocksByName;
+ bool mStructUsageFailed = false;
+
+ // For validateExpressionTypes:
+ bool mExpressionTypesFailed = false;
+
+ // For validateMultiDeclarations:
+ bool mMultiDeclarationsFailed = false;
+
+ // For validateNoSwizzleOfSwizzle:
+ bool mNoSwizzleOfSwizzleFailed = false;
+
+ // For validateNoStatementsAfterBranch:
+ bool mIsBranchVisitedInBlock = false;
+ bool mNoStatementsAfterBranchFailed = false;
+};
+
+bool IsSameType(const TType &a, const TType &b)
+{
+ return a.getBasicType() == b.getBasicType() && a.getNominalSize() == b.getNominalSize() &&
+ a.getSecondarySize() == b.getSecondarySize() && a.getArraySizes() == b.getArraySizes() &&
+ a.getStruct() == b.getStruct() &&
+ (!a.isInterfaceBlock() || a.getInterfaceBlock() == b.getInterfaceBlock());
+}
+
+bool ValidateAST::validate(TIntermNode *root,
+ TDiagnostics *diagnostics,
+ const ValidateASTOptions &options)
+{
+ ValidateAST validate(root, diagnostics, options);
+ root->traverse(&validate);
+ return validate.validateInternal();
+}
+
+ValidateAST::ValidateAST(TIntermNode *root,
+ TDiagnostics *diagnostics,
+ const ValidateASTOptions &options)
+ : TIntermTraverser(true, false, true, nullptr), mOptions(options), mDiagnostics(diagnostics)
+{
+ bool isTreeRoot = root->getAsBlock() && root->getAsBlock()->isTreeRoot();
+
+ // Some validations are not applicable unless run on the entire tree.
+ if (!isTreeRoot)
+ {
+ mOptions.validateVariableReferences = false;
+ mOptions.validateFunctionCall = false;
+ mOptions.validateStructUsage = false;
+ }
+
+ if (mOptions.validateSingleParent)
+ {
+ mParent[root] = nullptr;
+ }
+}
+
+void ValidateAST::visitNode(Visit visit, TIntermNode *node)
+{
+ if (visit == PreVisit && mOptions.validateSingleParent)
+ {
+ size_t childCount = node->getChildCount();
+ for (size_t i = 0; i < childCount; ++i)
+ {
+ TIntermNode *child = node->getChildNode(i);
+ if (mParent.find(child) != mParent.end())
+ {
+ // If child is visited twice but through the same parent, the problem is in one of
+ // the ancestors.
+ if (mParent[child] != node)
+ {
+ mDiagnostics->error(node->getLine(), "Found child with two parents",
+ "<validateSingleParent>");
+ mSingleParentFailed = true;
+ }
+ }
+
+ mParent[child] = node;
+ }
+ }
+
+ if (visit == PreVisit && mOptions.validateNoStatementsAfterBranch)
+ {
+ // If a branch has already been visited in this block, there should be no statements that
+ // follow. Only expected node visit should be PostVisit of the block.
+ if (mIsBranchVisitedInBlock)
+ {
+ mDiagnostics->error(node->getLine(), "Found dead code after branch",
+ "<validateNoStatementsAfterBranch>");
+ mNoStatementsAfterBranchFailed = true;
+ }
+ }
+}
+
+void ValidateAST::visitStructOrInterfaceBlockDeclaration(const TType &type,
+ const TSourceLoc &location)
+{
+ if (type.getStruct() == nullptr && type.getInterfaceBlock() == nullptr)
+ {
+ return;
+ }
+
+ // Make sure the structure or interface block is not doubly defined.
+ ImmutableString typeName("");
+ const TFieldListCollection *namedStructOrBlock = getStructOrInterfaceBlock(type, &typeName);
+
+ // Recurse the fields of the structure or interface block and check members of structure type.
+ // This is done before visiting the struct itself, because if the fields refer to a struct with
+ // the same name, they would be referencing the struct declared in an outer scope.
+ {
+ // Note that structOrBlock was previously only set for named structures, so make sure
+ // nameless structs are also recursed.
+ const TFieldListCollection *structOrBlock = namedStructOrBlock;
+ if (structOrBlock == nullptr)
+ {
+ structOrBlock = type.getStruct();
+ }
+ ASSERT(structOrBlock != nullptr);
+
+ for (const TField *field : structOrBlock->fields())
+ {
+ visitStructUsage(*field->type(), field->line());
+ }
+ }
+
+ if (namedStructOrBlock)
+ {
+ ASSERT(!typeName.empty());
+ // Structures are not allowed to be doubly defined
+ if (type.getStruct() == nullptr)
+ {
+ // Allow interfaces to be doubly-defined.
+ std::string name(typeName.data());
+
+ if (IsShaderIn(type.getQualifier()))
+ {
+ typeName = ImmutableString(name + "<input>");
+ }
+ else if (IsShaderOut(type.getQualifier()))
+ {
+ typeName = ImmutableString(name + "<output>");
+ }
+ else if (IsStorageBuffer(type.getQualifier()))
+ {
+ typeName = ImmutableString(name + "<buffer>");
+ }
+ else if (type.getQualifier() == EvqUniform)
+ {
+ typeName = ImmutableString(name + "<uniform>");
+ }
+ }
+
+ if (mStructsAndBlocksByName.back().find(typeName) != mStructsAndBlocksByName.back().end())
+ {
+ mDiagnostics->error(location,
+ "Found redeclaration of struct or interface block with the same "
+ "name in the same scope <validateStructUsage>",
+ typeName.data());
+ mStructUsageFailed = true;
+ }
+ else
+ {
+ // First encounter.
+ mStructsAndBlocksByName.back()[typeName] = namedStructOrBlock;
+ }
+ }
+}
+
+void ValidateAST::visitStructUsage(const TType &type, const TSourceLoc &location)
+{
+ if (type.getStruct() == nullptr)
+ {
+ return;
+ }
+
+ // Make sure the structure being referenced has the same pointer as the closest (in scope)
+ // definition.
+ const TStructure *structure = type.getStruct();
+ const ImmutableString &typeName = structure->name();
+
+ bool foundDeclaration = false;
+ for (size_t scopeIndex = mStructsAndBlocksByName.size(); scopeIndex > 0; --scopeIndex)
+ {
+ const std::map<ImmutableString, const TFieldListCollection *> &scopeDecls =
+ mStructsAndBlocksByName[scopeIndex - 1];
+
+ auto iter = scopeDecls.find(typeName);
+ if (iter != scopeDecls.end())
+ {
+ foundDeclaration = true;
+
+ if (iter->second != structure)
+ {
+ mDiagnostics->error(location,
+ "Found reference to struct or interface block with doubly "
+ "created type <validateStructUsage>",
+ typeName.data());
+ mStructUsageFailed = true;
+ }
+
+ break;
+ }
+ }
+
+ if (!foundDeclaration)
+ {
+ mDiagnostics->error(location,
+ "Found reference to struct or interface block with no declaration "
+ "<validateStructUsage>",
+ typeName.data());
+ mStructUsageFailed = true;
+ }
+}
+
+void ValidateAST::visitBuiltInFunction(TIntermOperator *node, const TFunction *function)
+{
+ const TOperator op = node->getOp();
+ if (!BuiltInGroup::IsBuiltIn(op))
+ {
+ return;
+ }
+
+ ImmutableStringBuilder opValueBuilder(16);
+ opValueBuilder << "op: ";
+ opValueBuilder.appendDecimal(op);
+
+ ImmutableString opValue = opValueBuilder;
+
+ if (function == nullptr)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found node calling built-in without a reference to the built-in "
+ "function <validateBuiltInOps>",
+ opValue.data());
+ mVariableReferencesFailed = true;
+ }
+ else if (function->getBuiltInOp() != op)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found node calling built-in with a reference to a different function "
+ "<validateBuiltInOps>",
+ opValue.data());
+ mVariableReferencesFailed = true;
+ }
+}
+
+void ValidateAST::visitFunctionCall(TIntermAggregate *node)
+{
+ if (node->getOp() != EOpCallFunctionInAST)
+ {
+ return;
+ }
+
+ const TFunction *function = node->getFunction();
+
+ if (function == nullptr)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found node calling function without a reference to it",
+ "<validateFunctionCall>");
+ mFunctionCallFailed = true;
+ }
+ else if (mDeclaredFunctions.find(function) == mDeclaredFunctions.end())
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found node calling previously undeclared function "
+ "<validateFunctionCall>",
+ function->name().data());
+ mFunctionCallFailed = true;
+ }
+}
+
+void ValidateAST::validateExpressionTypeBinary(TIntermBinary *node)
+{
+ switch (node->getOp())
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ {
+ TType expectedType(node->getLeft()->getType());
+ if (!expectedType.isArray())
+ {
+ // TODO: Validate matrix column selection and vector component selection.
+ // http://anglebug.com/2733
+ break;
+ }
+
+ expectedType.toArrayElementType();
+
+ if (!IsSameType(node->getType(), expectedType))
+ {
+ const TSymbol *symbol = expectedType.getStruct();
+ if (symbol == nullptr)
+ {
+ symbol = expectedType.getInterfaceBlock();
+ }
+ const char *name = nullptr;
+ if (symbol)
+ {
+ name = symbol->name().data();
+ }
+ else if (expectedType.isScalar())
+ {
+ name = "<scalar array>";
+ }
+ else if (expectedType.isVector())
+ {
+ name = "<vector array>";
+ }
+ else
+ {
+ ASSERT(expectedType.isMatrix());
+ name = "<matrix array>";
+ }
+
+ mDiagnostics->error(
+ node->getLine(),
+ "Found index node with type that is inconsistent with the array being indexed "
+ "<validateExpressionTypes>",
+ name);
+ mExpressionTypesFailed = true;
+ }
+ }
+ break;
+ default:
+ // TODO: Validate other expressions. http://anglebug.com/2733
+ break;
+ }
+
+ switch (node->getOp())
+ {
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ if (node->getRight()->getAsConstantUnion() == nullptr)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found direct index node with a non-constant index",
+ "<validateExpressionTypes>");
+ mExpressionTypesFailed = true;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void ValidateAST::validateExpressionTypeSwitch(TIntermSwitch *node)
+{
+ const TType &selectorType = node->getInit()->getType();
+
+ if (selectorType.getBasicType() != EbtYuvCscStandardEXT &&
+ selectorType.getBasicType() != EbtInt && selectorType.getBasicType() != EbtUInt)
+ {
+ mDiagnostics->error(node->getLine(), "Found switch selector expression that is not integer",
+ "<validateExpressionTypes>");
+ mExpressionTypesFailed = true;
+ }
+ else if (!selectorType.isScalar())
+ {
+ mDiagnostics->error(node->getLine(), "Found switch selector expression that is not scalar",
+ "<validateExpressionTypes>");
+ mExpressionTypesFailed = true;
+ }
+}
+
+void ValidateAST::visitVariableNeedingDeclaration(TIntermSymbol *node)
+{
+ const TVariable *variable = &node->variable();
+ const TType &type = node->getType();
+
+ // If it's a reference to a field of a nameless interface block, match it by index and name.
+ if (type.getInterfaceBlock() && !type.isInterfaceBlock())
+ {
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ const TFieldList &fieldList = interfaceBlock->fields();
+ const size_t fieldIndex = type.getInterfaceBlockFieldIndex();
+
+ if (mNamelessInterfaceBlocks.count(interfaceBlock) == 0)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found reference to undeclared or inconsistenly transformed "
+ "nameless interface block <validateVariableReferences>",
+ node->getName().data());
+ mVariableReferencesFailed = true;
+ }
+ else if (fieldIndex >= fieldList.size() || node->getName() != fieldList[fieldIndex]->name())
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found reference to inconsistenly transformed nameless "
+ "interface block field <validateVariableReferences>",
+ node->getName().data());
+ mVariableReferencesFailed = true;
+ }
+ return;
+ }
+
+ const bool isStructDeclaration =
+ type.isStructSpecifier() && variable->symbolType() == SymbolType::Empty;
+
+ if (!isStructDeclaration && !isVariableDeclared(variable))
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found reference to undeclared or inconsistently transformed "
+ "variable <validateVariableReferences>",
+ node->getName().data());
+ mVariableReferencesFailed = true;
+ }
+}
+
+void ValidateAST::visitBuiltInVariable(TIntermSymbol *node)
+{
+ const TVariable *variable = &node->variable();
+ ImmutableString name = variable->name();
+
+ if (mOptions.validateVariableReferences)
+ {
+ auto iter = mReferencedBuiltIns.find(name);
+ if (iter == mReferencedBuiltIns.end())
+ {
+ mReferencedBuiltIns[name] = variable;
+ return;
+ }
+
+ if (variable != iter->second)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found inconsistent references to built-in variable <validateVariableReferences>",
+ name.data());
+ mVariableReferencesFailed = true;
+ }
+ }
+
+ if (mOptions.validateQualifiers)
+ {
+ TQualifier qualifier = variable->getType().getQualifier();
+
+ if ((name == "gl_ClipDistance" && qualifier != EvqClipDistance) ||
+ (name == "gl_CullDistance" && qualifier != EvqCullDistance) ||
+ (name == "gl_LastFragData" && qualifier != EvqLastFragData))
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Incorrect qualifier applied to redeclared built-in <validateQualifiers>",
+ name.data());
+ mQualifiersFailed = true;
+ }
+ }
+}
+
+void ValidateAST::scope(Visit visit)
+{
+ if (mOptions.validateVariableReferences)
+ {
+ if (visit == PreVisit)
+ {
+ mDeclaredVariables.push_back({});
+ }
+ else if (visit == PostVisit)
+ {
+ mDeclaredVariables.pop_back();
+ }
+ }
+
+ if (mOptions.validateStructUsage)
+ {
+ if (visit == PreVisit)
+ {
+ mStructsAndBlocksByName.push_back({});
+ }
+ else if (visit == PostVisit)
+ {
+ mStructsAndBlocksByName.pop_back();
+ }
+ }
+}
+
+bool ValidateAST::isVariableDeclared(const TVariable *variable)
+{
+ ASSERT(mOptions.validateVariableReferences);
+
+ for (const std::set<const TVariable *> &scopeVariables : mDeclaredVariables)
+ {
+ if (scopeVariables.count(variable) > 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ValidateAST::variableNeedsDeclaration(const TVariable *variable)
+{
+ // Don't expect declaration for built-in variables.
+ if (gl::IsBuiltInName(variable->name().data()))
+ {
+ return false;
+ }
+
+ // Additionally, don't expect declaration for Vulkan specialization constants if not enabled.
+ // The declaration of these variables is deferred.
+ if (variable->getType().getQualifier() == EvqSpecConst)
+ {
+ return mOptions.validateSpecConstReferences;
+ }
+
+ return true;
+}
+
+const TFieldListCollection *ValidateAST::getStructOrInterfaceBlock(const TType &type,
+ ImmutableString *typeNameOut)
+{
+ const TStructure *structure = type.getStruct();
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+
+ ASSERT(structure != nullptr || interfaceBlock != nullptr);
+
+ // Make sure the structure or interface block is not doubly defined.
+ const TFieldListCollection *structOrBlock = nullptr;
+ if (structure != nullptr && structure->symbolType() != SymbolType::Empty)
+ {
+ structOrBlock = structure;
+ *typeNameOut = structure->name();
+ }
+ else if (interfaceBlock != nullptr)
+ {
+ structOrBlock = interfaceBlock;
+ *typeNameOut = interfaceBlock->name();
+ }
+
+ return structOrBlock;
+}
+
+void ValidateAST::expectNonNullChildren(Visit visit, TIntermNode *node, size_t least_count)
+{
+ if (visit == PreVisit && mOptions.validateNullNodes)
+ {
+ size_t childCount = node->getChildCount();
+ if (childCount < least_count)
+ {
+ mDiagnostics->error(node->getLine(), "Too few children", "<validateNullNodes>");
+ mNullNodesFailed = true;
+ }
+
+ for (size_t i = 0; i < childCount; ++i)
+ {
+ if (node->getChildNode(i) == nullptr)
+ {
+ mDiagnostics->error(node->getLine(), "Found nullptr child", "<validateNullNodes>");
+ mNullNodesFailed = true;
+ }
+ }
+ }
+}
+
+void ValidateAST::visitSymbol(TIntermSymbol *node)
+{
+ visitNode(PreVisit, node);
+
+ const TVariable *variable = &node->variable();
+
+ if (mOptions.validateVariableReferences)
+ {
+ if (variableNeedsDeclaration(variable))
+ {
+ visitVariableNeedingDeclaration(node);
+ }
+ }
+
+ const bool isBuiltIn = gl::IsBuiltInName(variable->name().data());
+ if (isBuiltIn)
+ {
+ visitBuiltInVariable(node);
+ }
+
+ if (mOptions.validatePrecision)
+ {
+ if (!isBuiltIn && IsPrecisionApplicableToType(node->getBasicType()) &&
+ node->getType().getPrecision() == EbpUndefined)
+ {
+ // Note that some built-ins don't have a precision.
+ mDiagnostics->error(node->getLine(),
+ "Found symbol with undefined precision <validatePrecision>",
+ variable->name().data());
+ mPrecisionFailed = true;
+ }
+ }
+}
+
+void ValidateAST::visitConstantUnion(TIntermConstantUnion *node)
+{
+ visitNode(PreVisit, node);
+}
+
+bool ValidateAST::visitSwizzle(Visit visit, TIntermSwizzle *node)
+{
+ visitNode(visit, node);
+
+ if (mOptions.validateNoSwizzleOfSwizzle)
+ {
+ if (node->getOperand()->getAsSwizzleNode() != nullptr)
+ {
+ mDiagnostics->error(node->getLine(), "Found swizzle applied to swizzle",
+ "<validateNoSwizzleOfSwizzle>");
+ mNoSwizzleOfSwizzleFailed = true;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitBinary(Visit visit, TIntermBinary *node)
+{
+ visitNode(visit, node);
+
+ if (mOptions.validateExpressionTypes && visit == PreVisit)
+ {
+ validateExpressionTypeBinary(node);
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitUnary(Visit visit, TIntermUnary *node)
+{
+ visitNode(visit, node);
+
+ if (visit == PreVisit && mOptions.validateBuiltInOps)
+ {
+ visitBuiltInFunction(node, node->getFunction());
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitTernary(Visit visit, TIntermTernary *node)
+{
+ visitNode(visit, node);
+ return true;
+}
+
+bool ValidateAST::visitIfElse(Visit visit, TIntermIfElse *node)
+{
+ visitNode(visit, node);
+ return true;
+}
+
+bool ValidateAST::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ visitNode(visit, node);
+
+ if (mOptions.validateExpressionTypes && visit == PreVisit)
+ {
+ validateExpressionTypeSwitch(node);
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitCase(Visit visit, TIntermCase *node)
+{
+ // Case is allowed to come after a branch, and for dead-code-elimination purposes acts as if a
+ // new block is started.
+ mIsBranchVisitedInBlock = false;
+
+ visitNode(visit, node);
+
+ return true;
+}
+
+void ValidateAST::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ visitNode(PreVisit, node);
+
+ if (mOptions.validateFunctionCall)
+ {
+ const TFunction *function = node->getFunction();
+ mDeclaredFunctions.insert(function);
+ }
+
+ const TFunction *function = node->getFunction();
+ const TType &returnType = function->getReturnType();
+ if (mOptions.validatePrecision && IsPrecisionApplicableToType(returnType.getBasicType()) &&
+ returnType.getPrecision() == EbpUndefined)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found function with undefined precision on return value <validatePrecision>",
+ function->name().data());
+ mPrecisionFailed = true;
+ }
+
+ if (mOptions.validateStructUsage)
+ {
+ if (returnType.isStructSpecifier())
+ {
+ visitStructOrInterfaceBlockDeclaration(returnType, node->getLine());
+ }
+ else
+ {
+ visitStructUsage(returnType, node->getLine());
+ }
+ }
+
+ for (size_t paramIndex = 0; paramIndex < function->getParamCount(); ++paramIndex)
+ {
+ const TVariable *param = function->getParam(paramIndex);
+ const TType &paramType = param->getType();
+
+ if (mOptions.validateStructUsage)
+ {
+ visitStructUsage(paramType, node->getLine());
+ }
+
+ if (mOptions.validateQualifiers)
+ {
+ TQualifier qualifier = paramType.getQualifier();
+ if (qualifier != EvqParamIn && qualifier != EvqParamOut && qualifier != EvqParamInOut &&
+ qualifier != EvqParamConst)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found function prototype with an invalid qualifier "
+ "<validateQualifiers>",
+ param->name().data());
+ mQualifiersFailed = true;
+ }
+
+ if (IsOpaqueType(paramType.getBasicType()) && qualifier != EvqParamIn)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found function prototype with an invalid qualifier on opaque parameter "
+ "<validateQualifiers>",
+ param->name().data());
+ mQualifiersFailed = true;
+ }
+ }
+
+ if (mOptions.validatePrecision && IsPrecisionApplicableToType(paramType.getBasicType()) &&
+ paramType.getPrecision() == EbpUndefined)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found function parameter with undefined precision <validatePrecision>",
+ param->name().data());
+ mPrecisionFailed = true;
+ }
+ }
+}
+
+bool ValidateAST::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+{
+ visitNode(visit, node);
+ scope(visit);
+
+ if (mOptions.validateVariableReferences && visit == PreVisit)
+ {
+ const TFunction *function = node->getFunction();
+
+ size_t paramCount = function->getParamCount();
+ for (size_t paramIndex = 0; paramIndex < paramCount; ++paramIndex)
+ {
+ const TVariable *variable = function->getParam(paramIndex);
+
+ if (isVariableDeclared(variable))
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found two declarations of the same function argument "
+ "<validateVariableReferences>",
+ variable->name().data());
+ mVariableReferencesFailed = true;
+ break;
+ }
+
+ mDeclaredVariables.back().insert(variable);
+ }
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ visitNode(visit, node);
+ expectNonNullChildren(visit, node, 0);
+
+ if (visit == PreVisit && mOptions.validateBuiltInOps)
+ {
+ visitBuiltInFunction(node, node->getFunction());
+ }
+
+ if (visit == PreVisit && mOptions.validateFunctionCall)
+ {
+ visitFunctionCall(node);
+ }
+
+ if (visit == PreVisit && mOptions.validateNoRawFunctionCalls)
+ {
+ if (node->getOp() == EOpCallInternalRawFunction)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found node calling a raw function (deprecated) "
+ "<validateNoRawFunctionCalls>",
+ node->getFunction()->name().data());
+ mNoRawFunctionCallsFailed = true;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitBlock(Visit visit, TIntermBlock *node)
+{
+ visitNode(visit, node);
+ scope(visit);
+ expectNonNullChildren(visit, node, 0);
+
+ if (visit == PostVisit)
+ {
+ // If the parent is a block and mIsBranchVisitedInBlock is set, this is a nested block
+ // without any condition (like if, loop or switch), so the rest of the parent block is also
+ // dead code. Otherwise the parent block can contain code after this.
+ if (getParentNode() == nullptr || getParentNode()->getAsBlock() == nullptr)
+ {
+ mIsBranchVisitedInBlock = false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+{
+ visitNode(visit, node);
+
+ const TVariable *variable = &node->getSymbol()->variable();
+
+ if (mOptions.validateVariableReferences && variableNeedsDeclaration(variable))
+ {
+ if (!isVariableDeclared(variable))
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found reference to undeclared or inconsistently transformed "
+ "variable <validateVariableReferences>",
+ variable->name().data());
+ mVariableReferencesFailed = true;
+ }
+ }
+ return true;
+}
+
+bool ValidateAST::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ visitNode(visit, node);
+ expectNonNullChildren(visit, node, 0);
+
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ if (mOptions.validateMultiDeclarations && sequence.size() > 1)
+ {
+ TIntermSymbol *symbol = sequence[1]->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ TIntermBinary *init = sequence[1]->getAsBinaryNode();
+ ASSERT(init && init->getOp() == EOpInitialize);
+ symbol = init->getLeft()->getAsSymbolNode();
+ }
+ ASSERT(symbol);
+
+ mDiagnostics->error(node->getLine(),
+ "Found multiple declarations where SeparateDeclarations should have "
+ "separated them <validateMultiDeclarations>",
+ symbol->variable().name().data());
+ mMultiDeclarationsFailed = true;
+ }
+
+ if (visit == PreVisit)
+ {
+ bool validateStructUsage = mOptions.validateStructUsage;
+
+ for (TIntermNode *instance : sequence)
+ {
+ TIntermSymbol *symbol = instance->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ TIntermBinary *init = instance->getAsBinaryNode();
+ ASSERT(init && init->getOp() == EOpInitialize);
+ symbol = init->getLeft()->getAsSymbolNode();
+ }
+ ASSERT(symbol);
+
+ const TVariable *variable = &symbol->variable();
+ const TType &type = variable->getType();
+
+ if (mOptions.validateVariableReferences)
+ {
+ if (isVariableDeclared(variable))
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found two declarations of the same variable <validateVariableReferences>",
+ variable->name().data());
+ mVariableReferencesFailed = true;
+ break;
+ }
+
+ mDeclaredVariables.back().insert(variable);
+
+ const TInterfaceBlock *interfaceBlock = variable->getType().getInterfaceBlock();
+
+ if (variable->symbolType() == SymbolType::Empty && interfaceBlock != nullptr)
+ {
+ // Nameless interface blocks can only be declared at the top level. Their
+ // fields are matched by field index, and then verified to match by name.
+ // Conflict in names should have already generated a compile error.
+ ASSERT(mDeclaredVariables.size() == 1);
+ ASSERT(mNamelessInterfaceBlocks.count(interfaceBlock) == 0);
+
+ mNamelessInterfaceBlocks.insert(interfaceBlock);
+ }
+ }
+
+ if (validateStructUsage)
+ {
+ // Only declare and/or validate the struct once.
+ validateStructUsage = false;
+
+ if (type.isStructSpecifier() || type.isInterfaceBlock())
+ {
+ visitStructOrInterfaceBlockDeclaration(type, node->getLine());
+ }
+ else
+ {
+ visitStructUsage(type, node->getLine());
+ }
+ }
+
+ if (gl::IsBuiltInName(variable->name().data()))
+ {
+ visitBuiltInVariable(symbol);
+ }
+
+ if (mOptions.validatePrecision && (type.isStructSpecifier() || type.isInterfaceBlock()))
+ {
+ const TFieldListCollection *structOrBlock = type.getStruct();
+ if (structOrBlock == nullptr)
+ {
+ structOrBlock = type.getInterfaceBlock();
+ }
+
+ for (const TField *field : structOrBlock->fields())
+ {
+ const TType *fieldType = field->type();
+ if (IsPrecisionApplicableToType(fieldType->getBasicType()) &&
+ fieldType->getPrecision() == EbpUndefined)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found block field with undefined precision <validatePrecision>",
+ field->name().data());
+ mPrecisionFailed = true;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitLoop(Visit visit, TIntermLoop *node)
+{
+ visitNode(visit, node);
+ return true;
+}
+
+bool ValidateAST::visitBranch(Visit visit, TIntermBranch *node)
+{
+ visitNode(visit, node);
+
+ if (visit == PostVisit)
+ {
+ mIsBranchVisitedInBlock = true;
+ }
+
+ return true;
+}
+
+void ValidateAST::visitPreprocessorDirective(TIntermPreprocessorDirective *node)
+{
+ visitNode(PreVisit, node);
+}
+
+bool ValidateAST::validateInternal()
+{
+ return !mSingleParentFailed && !mVariableReferencesFailed && !mBuiltInOpsFailed &&
+ !mFunctionCallFailed && !mNoRawFunctionCallsFailed && !mNullNodesFailed &&
+ !mQualifiersFailed && !mPrecisionFailed && !mStructUsageFailed &&
+ !mExpressionTypesFailed && !mMultiDeclarationsFailed && !mNoSwizzleOfSwizzleFailed &&
+ !mNoStatementsAfterBranchFailed;
+}
+
+} // anonymous namespace
+
+bool ValidateAST(TIntermNode *root, TDiagnostics *diagnostics, const ValidateASTOptions &options)
+{
+ // ValidateAST is called after transformations, so if |validateNoMoreTransformations| is set,
+ // it's immediately an error.
+ if (options.validateNoMoreTransformations)
+ {
+ diagnostics->error(kNoSourceLoc, "Unexpected transformation after AST post-processing",
+ "<validateNoMoreTransformations>");
+ return false;
+ }
+
+ return ValidateAST::validate(root, diagnostics, options);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateAST.h b/gfx/angle/checkout/src/compiler/translator/ValidateAST.h
new file mode 100644
index 0000000000..2fa73db9fb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateAST.h
@@ -0,0 +1,108 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATEAST_H_
+#define COMPILER_TRANSLATOR_VALIDATEAST_H_
+
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+class TDiagnostics;
+class TIntermNode;
+
+// The following options (stored in Compiler) tell the validator what to validate. Some validations
+// are conditional to certain passes.
+struct ValidateASTOptions
+{
+ // TODO: add support for the flags marked with TODO. http://anglebug.com/2733
+
+ // Check that every node always has only one parent,
+ bool validateSingleParent = true;
+ // Check that all symbols reference TVariables that have been declared. For built-ins, this
+ // makes sure that the same GLSL built-in uses the same TVariable consistently.
+ bool validateVariableReferences = true;
+ // Whether validateVariableReferences should also include specialization constants. Their
+ // declaration is output after their usage is discovered, so this is disabled until then.
+ bool validateSpecConstReferences = false;
+ // Check that TIntermUnary and TIntermAggregate nodes with a built-in op reference a function
+ // with said op.
+ bool validateBuiltInOps = true;
+ // Check that all EOpCallFunctionInAST have their corresponding function definitions in the AST,
+ // with matching symbol ids. There should also be at least a prototype declaration before the
+ // function is called.
+ bool validateFunctionCall = true;
+ // Check that EOpCallInternalRawFunction is not used. This OP is deprecated and needs to be
+ // removed. http://anglebug.com/6059
+ bool validateNoRawFunctionCalls = true;
+ // Check that there are no null nodes where they are not allowed, for example as children of
+ // TIntermDeclaration or TIntermBlock.
+ bool validateNullNodes = true;
+ // Check that symbols that reference variables have consistent qualifiers and symbol ids with
+ // the variable declaration. The following needs to be validated:
+ //
+ // Implemented:
+ //
+ // - Function parameters having one of EvqParam* qualifiers.
+ // - No const qualifier on opaque function parameters.
+ // - gl_ClipDistance, gl_CullDistance and gl_LastFragData are correctly qualified even when
+ // redeclared in the shader.
+ //
+ // TODO:
+ //
+ // - Function-local variables must have the EvqTemporary qualifier.
+ // - Symbol references and declarations have identical qualifiers.
+ bool validateQualifiers = true;
+ // Check that every symbol has its precision specified. That includes variables, block members,
+ // function parameters and return values.
+ bool validatePrecision = true;
+ // Check that variable declarations that can't have initializers don't have initializers
+ // (varyings, uniforms for example).
+ bool validateInitializers = true; // TODO
+ // Check that there is only one TFunction with each function name referenced in the nodes (no
+ // two TFunctions with the same name, taking internal/non-internal namespaces into account).
+ bool validateUniqueFunctions = true; // TODO
+ // Check that references to structs are matched with the corresponding struct declaration.
+ bool validateStructUsage = true;
+ // Check that expression nodes have the correct type considering their operand(s). The
+ // following validation is possible:
+ //
+ // Implemented:
+ //
+ // - Binary node that indexes T[] should have type T
+ // - Binary nodes with EOpIndexDirect* should have a constant as the right node
+ // - Switch nodes should have an integer type in the selector
+ //
+ // TODO:
+ //
+ // - Function calls (including built-ins) have the same return type in the node and function.
+ // - Unary and binary operators have the correct type based on operands
+ // - Swizzle result has same type as the operand except for vector size
+ // - Ternary operator has the same type as the operands
+ // - Case expressions have the same type as the switch selector
+ bool validateExpressionTypes = true;
+ // If SeparateDeclarations has been run, check for the absence of multi declarations as well.
+ bool validateMultiDeclarations = false;
+ // If PruneNoOps has been run, check that no statements are ever added after branches in the
+ // same block. Those statements would be dead code.
+ bool validateNoStatementsAfterBranch = false;
+ // Check that swizzle is not applied to swizzle. Swizzles of swizzles are folded in
+ // TIntermSwizzle::fold.
+ bool validateNoSwizzleOfSwizzle = true;
+
+ // Once set, disallows any further transformations on the tree. Used before AST post-processing
+ // which requires that the tree remains unmodified.
+ bool validateNoMoreTransformations = false;
+};
+
+// Check for errors and output error messages on the context.
+// Returns true if there are no errors.
+bool ValidateAST(TIntermNode *root, TDiagnostics *diagnostics, const ValidateASTOptions &options);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATESWITCH_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.cpp
new file mode 100644
index 0000000000..c36406ea59
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.cpp
@@ -0,0 +1,100 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ValidateBarrierFunctionCalls:
+// Runs compilation checks related to the "barrier built-in function.
+
+#include "compiler/translator/ValidateBarrierFunctionCall.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+class Traverser : public TIntermTraverser
+{
+ public:
+ Traverser(TDiagnostics *diagnostics)
+ : TIntermTraverser(true, false, true), mDiagnostics(diagnostics)
+ {}
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ if (!node->getFunction()->isMain())
+ {
+ return false;
+ }
+
+ mInMain = visit == PreVisit;
+ return true;
+ }
+
+ bool visitBranch(Visit visit, TIntermBranch *branch) override
+ {
+ if (branch->getFlowOp() == EOpReturn)
+ {
+ mSeenReturn = true;
+ }
+
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (node->getOp() != EOpBarrierTCS)
+ {
+ return true;
+ }
+
+ if (mSeenReturn)
+ {
+ mDiagnostics->error(node->getLine(),
+ "barrier() may not be called at any point after a return statement "
+ "in the function main().",
+ "barrier");
+ mValid = false;
+ return false;
+ }
+
+ // TODO(anglebug.com/5557): Determine if we should check loops as well.
+ if (mBranchCount > 0)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "barrier() may not be called in potentially divergent flow control.", "barrier");
+ mValid = false;
+ return false;
+ }
+
+ return true;
+ }
+
+ bool visitIfElse(Visit visit, TIntermIfElse *node) override
+ {
+ mBranchCount += ((visit == PreVisit) ? 1 : -1);
+ return true;
+ }
+
+ bool valid() const { return mValid; }
+
+ private:
+ TDiagnostics *mDiagnostics = nullptr;
+ bool mInMain = false;
+ bool mSeenReturn = false;
+ bool mValid = true;
+ uint32_t mBranchCount = 0;
+};
+} // anonymous namespace
+
+bool ValidateBarrierFunctionCall(TIntermBlock *root, TDiagnostics *diagnostics)
+{
+ Traverser traverser(diagnostics);
+ root->traverse(&traverser);
+ return traverser.valid();
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.h b/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.h
new file mode 100644
index 0000000000..6b91eb456a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.h
@@ -0,0 +1,22 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ValidateBarrierFunctionCalls:
+// Runs compilation checks related to the "barrier built-in function.
+
+#ifndef COMPILER_TRANSLATOR_VALIDATEBARRIERFUNCTIONCALL_H_
+#define COMPILER_TRANSLATOR_VALIDATEBARRIERFUNCTIONCALL_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TDiagnostics;
+class TIntermBlock;
+
+[[nodiscard]] bool ValidateBarrierFunctionCall(TIntermBlock *root, TDiagnostics *diagnostics);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATEBARRIERFUNCTIONCALL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.cpp
new file mode 100644
index 0000000000..3ecd8b4295
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.cpp
@@ -0,0 +1,200 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The ValidateClipCullDistance function checks if the sum of array sizes for gl_ClipDistance and
+// gl_CullDistance exceeds gl_MaxCombinedClipAndCullDistances
+//
+
+#include "ValidateClipCullDistance.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
+{
+ diagnostics->error(symbol.getLine(), reason, symbol.getName().data());
+}
+
+class ValidateClipCullDistanceTraverser : public TIntermTraverser
+{
+ public:
+ ValidateClipCullDistanceTraverser();
+ void validate(TDiagnostics *diagnostics, const unsigned int maxCombinedClipAndCullDistances);
+
+ private:
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+
+ unsigned int mClipDistanceSize;
+ unsigned int mCullDistanceSize;
+
+ unsigned int mMaxClipDistanceIndex;
+ unsigned int mMaxCullDistanceIndex;
+
+ const TIntermSymbol *mClipDistance;
+ const TIntermSymbol *mCullDistance;
+};
+
+ValidateClipCullDistanceTraverser::ValidateClipCullDistanceTraverser()
+ : TIntermTraverser(true, false, false),
+ mClipDistanceSize(0),
+ mCullDistanceSize(0),
+ mMaxClipDistanceIndex(0),
+ mMaxCullDistanceIndex(0),
+ mClipDistance(nullptr),
+ mCullDistance(nullptr)
+{}
+
+bool ValidateClipCullDistanceTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ if (sequence.size() != 1)
+ {
+ return true;
+ }
+
+ const TIntermSymbol *symbol = sequence.front()->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ return true;
+ }
+
+ if (symbol->getName() == "gl_ClipDistance")
+ {
+ mClipDistanceSize = symbol->getOutermostArraySize();
+ mClipDistance = symbol;
+ }
+ else if (symbol->getName() == "gl_CullDistance")
+ {
+ mCullDistanceSize = symbol->getOutermostArraySize();
+ mCullDistance = symbol;
+ }
+
+ return true;
+}
+
+bool ValidateClipCullDistanceTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ TOperator op = node->getOp();
+ if (op != EOpIndexDirect && op != EOpIndexIndirect)
+ {
+ return true;
+ }
+
+ TIntermSymbol *left = node->getLeft()->getAsSymbolNode();
+ if (!left)
+ {
+ return true;
+ }
+
+ ImmutableString varName(left->getName());
+ if (varName != "gl_ClipDistance" && varName != "gl_CullDistance")
+ {
+ return true;
+ }
+
+ const TConstantUnion *constIdx = node->getRight()->getConstantValue();
+ if (constIdx)
+ {
+ unsigned int idx = 0;
+ switch (constIdx->getType())
+ {
+ case EbtInt:
+ idx = constIdx->getIConst();
+ break;
+ case EbtUInt:
+ idx = constIdx->getUConst();
+ break;
+ case EbtFloat:
+ idx = static_cast<unsigned int>(constIdx->getFConst());
+ break;
+ case EbtBool:
+ idx = constIdx->getBConst() ? 1 : 0;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (varName == "gl_ClipDistance")
+ {
+ if (idx > mMaxClipDistanceIndex)
+ {
+ mMaxClipDistanceIndex = idx;
+ if (!mClipDistance)
+ {
+ mClipDistance = left;
+ }
+ }
+ }
+ else
+ {
+ ASSERT(varName == "gl_CullDistance");
+ if (idx > mMaxCullDistanceIndex)
+ {
+ mMaxCullDistanceIndex = idx;
+ if (!mCullDistance)
+ {
+ mCullDistance = left;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+void ValidateClipCullDistanceTraverser::validate(TDiagnostics *diagnostics,
+ const unsigned int maxCombinedClipAndCullDistances)
+{
+ ASSERT(diagnostics);
+
+ unsigned int enabledClipDistances =
+ (mClipDistanceSize > 0 ? mClipDistanceSize
+ : (mClipDistance ? mMaxClipDistanceIndex + 1 : 0));
+ unsigned int enabledCullDistances =
+ (mCullDistanceSize > 0 ? mCullDistanceSize
+ : (mCullDistance ? mMaxCullDistanceIndex + 1 : 0));
+ unsigned int combinedClipAndCullDistances =
+ (enabledClipDistances > 0 && enabledCullDistances > 0
+ ? enabledClipDistances + enabledCullDistances
+ : 0);
+
+ if (combinedClipAndCullDistances > maxCombinedClipAndCullDistances)
+ {
+ const TIntermSymbol *greaterSymbol =
+ (enabledClipDistances >= enabledCullDistances ? mClipDistance : mCullDistance);
+
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
+ strstr << "The sum of 'gl_ClipDistance' and 'gl_CullDistance' size is greater than "
+ "gl_MaxCombinedClipAndCullDistances ("
+ << combinedClipAndCullDistances << " > " << maxCombinedClipAndCullDistances << ")";
+ error(*greaterSymbol, strstr.str().c_str(), diagnostics);
+ }
+}
+
+} // anonymous namespace
+
+bool ValidateClipCullDistance(TIntermBlock *root,
+ TDiagnostics *diagnostics,
+ const unsigned int maxCombinedClipAndCullDistances)
+{
+ ValidateClipCullDistanceTraverser varyingValidator;
+ root->traverse(&varyingValidator);
+ int numErrorsBefore = diagnostics->numErrors();
+ varyingValidator.validate(diagnostics, maxCombinedClipAndCullDistances);
+ return (diagnostics->numErrors() == numErrorsBefore);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.h b/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.h
new file mode 100644
index 0000000000..31ea890cd7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The ValidateClipCullDistance function checks if the sum of array sizes for gl_ClipDistance and
+// gl_CullDistance exceeds gl_MaxCombinedClipAndCullDistances
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATECLIPCULLDISTANCE_H_
+#define COMPILER_TRANSLATOR_VALIDATECLIPCULLDISTANCE_H_
+
+#include "GLSLANG/ShaderVars.h"
+
+namespace sh
+{
+
+class TIntermBlock;
+class TDiagnostics;
+
+bool ValidateClipCullDistance(TIntermBlock *root,
+ TDiagnostics *diagnostics,
+ const unsigned int maxCombinedClipAndCullDistances);
+
+} // namespace sh
+
+#endif
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp
new file mode 100644
index 0000000000..126e8d7854
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp
@@ -0,0 +1,157 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/ValidateGlobalInitializer.h"
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+const int kMaxAllowedTraversalDepth = 256;
+
+class ValidateGlobalInitializerTraverser : public TIntermTraverser
+{
+ public:
+ ValidateGlobalInitializerTraverser(int shaderVersion,
+ bool isWebGL,
+ bool hasExtNonConstGlobalInitializers);
+
+ void visitSymbol(TIntermSymbol *node) override;
+ void visitConstantUnion(TIntermConstantUnion *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+
+ bool isValid() const { return mIsValid && mMaxDepth < mMaxAllowedDepth; }
+ bool issueWarning() const { return mIssueWarning; }
+
+ private:
+ ANGLE_INLINE void onNonConstInitializerVisit(bool accept)
+ {
+ if (accept)
+ {
+ if (!mExtNonConstGlobalInitializers)
+ {
+ mIssueWarning = true;
+ }
+ }
+ else
+ {
+ mIsValid = false;
+ }
+ }
+
+ int mShaderVersion;
+ bool mIsWebGL;
+ bool mExtNonConstGlobalInitializers;
+ bool mIsValid;
+ bool mIssueWarning;
+};
+
+void ValidateGlobalInitializerTraverser::visitSymbol(TIntermSymbol *node)
+{
+ // ESSL 1.00 section 4.3 (or ESSL 3.00 section 4.3):
+ // Global initializers must be constant expressions.
+ switch (node->getType().getQualifier())
+ {
+ case EvqConst:
+ break;
+ case EvqGlobal:
+ case EvqTemporary:
+ case EvqUniform:
+ // We allow these cases to be compatible with legacy ESSL 1.00 content.
+ // Implement stricter rules for ESSL 3.00 since there's no legacy content to deal
+ // with.
+ onNonConstInitializerVisit(mExtNonConstGlobalInitializers ||
+ ((mShaderVersion < 300) && mIsWebGL));
+ break;
+ default:
+ mIsValid = false;
+ }
+}
+
+void ValidateGlobalInitializerTraverser::visitConstantUnion(TIntermConstantUnion *node)
+{
+ // Constant unions that are not constant expressions may result from folding a ternary
+ // expression.
+ switch (node->getType().getQualifier())
+ {
+ case EvqConst:
+ break;
+ case EvqTemporary:
+ onNonConstInitializerVisit(mExtNonConstGlobalInitializers ||
+ ((mShaderVersion < 300) && mIsWebGL));
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+bool ValidateGlobalInitializerTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ // Disallow calls to user-defined functions and texture lookup functions in global variable
+ // initializers. For simplicity, all non-math built-in calls are disallowed.
+ if (node->isFunctionCall() ||
+ (BuiltInGroup::IsBuiltIn(node->getOp()) && !BuiltInGroup::IsMath(node->getOp())))
+ {
+ onNonConstInitializerVisit(mExtNonConstGlobalInitializers);
+ }
+ return true;
+}
+
+bool ValidateGlobalInitializerTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (node->isAssignment())
+ {
+ onNonConstInitializerVisit(mExtNonConstGlobalInitializers);
+ }
+ return true;
+}
+
+bool ValidateGlobalInitializerTraverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ if (node->isAssignment())
+ {
+ onNonConstInitializerVisit(mExtNonConstGlobalInitializers);
+ }
+ return true;
+}
+
+ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(
+ int shaderVersion,
+ bool isWebGL,
+ bool hasExtNonConstGlobalInitializers)
+ : TIntermTraverser(true, false, false, nullptr),
+ mShaderVersion(shaderVersion),
+ mIsWebGL(isWebGL),
+ mExtNonConstGlobalInitializers(hasExtNonConstGlobalInitializers),
+ mIsValid(true),
+ mIssueWarning(false)
+{
+ setMaxAllowedDepth(kMaxAllowedTraversalDepth);
+}
+
+} // namespace
+
+bool ValidateGlobalInitializer(TIntermTyped *initializer,
+ int shaderVersion,
+ bool isWebGL,
+ bool hasExtNonConstGlobalInitializers,
+ bool *warning)
+{
+ ValidateGlobalInitializerTraverser validate(shaderVersion, isWebGL,
+ hasExtNonConstGlobalInitializers);
+ initializer->traverse(&validate);
+ ASSERT(warning != nullptr);
+ *warning = validate.issueWarning();
+ return validate.isValid();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.h b/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.h
new file mode 100644
index 0000000000..cb4b652b18
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
+#define COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
+
+namespace sh
+{
+
+class TIntermTyped;
+
+// Returns true if the initializer is valid.
+bool ValidateGlobalInitializer(TIntermTyped *initializer,
+ int shaderVersion,
+ bool isWebGL,
+ bool hasExtNonConstGlobalInitializers,
+ bool *warning);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp
new file mode 100644
index 0000000000..5ca3daca0f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp
@@ -0,0 +1,452 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/ValidateLimitations.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/ParseContext.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+int GetLoopSymbolId(TIntermLoop *loop)
+{
+ // Here we assume all the operations are valid, because the loop node is
+ // already validated before this call.
+ TIntermSequence *declSeq = loop->getInit()->getAsDeclarationNode()->getSequence();
+ TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode();
+ TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode();
+
+ return symbol->uniqueId().get();
+}
+
+// Traverses a node to check if it represents a constant index expression.
+// Definition:
+// constant-index-expressions are a superset of constant-expressions.
+// Constant-index-expressions can include loop indices as defined in
+// GLSL ES 1.0 spec, Appendix A, section 4.
+// The following are constant-index-expressions:
+// - Constant expressions
+// - Loop indices as defined in section 4
+// - Expressions composed of both of the above
+class ValidateConstIndexExpr : public TIntermTraverser
+{
+ public:
+ ValidateConstIndexExpr(const std::vector<int> &loopSymbols)
+ : TIntermTraverser(true, false, false), mValid(true), mLoopSymbolIds(loopSymbols)
+ {}
+
+ // Returns true if the parsed node represents a constant index expression.
+ bool isValid() const { return mValid; }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ // Only constants and loop indices are allowed in a
+ // constant index expression.
+ if (mValid)
+ {
+ bool isLoopSymbol = std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(),
+ symbol->uniqueId().get()) != mLoopSymbolIds.end();
+ mValid = (symbol->getQualifier() == EvqConst) || isLoopSymbol;
+ }
+ }
+
+ private:
+ bool mValid;
+ const std::vector<int> mLoopSymbolIds;
+};
+
+// Traverses intermediate tree to ensure that the shader does not exceed the
+// minimum functionality mandated in GLSL 1.0 spec, Appendix A.
+class ValidateLimitationsTraverser : public TLValueTrackingTraverser
+{
+ public:
+ ValidateLimitationsTraverser(sh::GLenum shaderType,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics);
+
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitBinary(Visit, TIntermBinary *) override;
+ bool visitLoop(Visit, TIntermLoop *) override;
+
+ private:
+ void error(TSourceLoc loc, const char *reason, const char *token);
+ void error(TSourceLoc loc, const char *reason, const ImmutableString &token);
+
+ bool isLoopIndex(TIntermSymbol *symbol);
+ bool validateLoopType(TIntermLoop *node);
+
+ bool validateForLoopHeader(TIntermLoop *node);
+ // If valid, return the index symbol id; Otherwise, return -1.
+ int validateForLoopInit(TIntermLoop *node);
+ bool validateForLoopCond(TIntermLoop *node, int indexSymbolId);
+ bool validateForLoopExpr(TIntermLoop *node, int indexSymbolId);
+
+ // Returns true if indexing does not exceed the minimum functionality
+ // mandated in GLSL 1.0 spec, Appendix A, Section 5.
+ bool isConstExpr(TIntermNode *node);
+ bool isConstIndexExpr(TIntermNode *node);
+ bool validateIndexing(TIntermBinary *node);
+
+ sh::GLenum mShaderType;
+ TDiagnostics *mDiagnostics;
+ std::vector<int> mLoopSymbolIds;
+};
+
+ValidateLimitationsTraverser::ValidateLimitationsTraverser(sh::GLenum shaderType,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics)
+ : TLValueTrackingTraverser(true, false, false, symbolTable),
+ mShaderType(shaderType),
+ mDiagnostics(diagnostics)
+{
+ ASSERT(diagnostics);
+}
+
+void ValidateLimitationsTraverser::visitSymbol(TIntermSymbol *node)
+{
+ if (isLoopIndex(node) && isLValueRequiredHere())
+ {
+ error(node->getLine(),
+ "Loop index cannot be statically assigned to within the body of the loop",
+ node->getName());
+ }
+}
+
+bool ValidateLimitationsTraverser::visitBinary(Visit, TIntermBinary *node)
+{
+ // Check indexing.
+ switch (node->getOp())
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ validateIndexing(node);
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+bool ValidateLimitationsTraverser::visitLoop(Visit, TIntermLoop *node)
+{
+ if (!validateLoopType(node))
+ return false;
+
+ if (!validateForLoopHeader(node))
+ return false;
+
+ TIntermNode *body = node->getBody();
+ if (body != nullptr)
+ {
+ mLoopSymbolIds.push_back(GetLoopSymbolId(node));
+ body->traverse(this);
+ mLoopSymbolIds.pop_back();
+ }
+
+ // The loop is fully processed - no need to visit children.
+ return false;
+}
+
+void ValidateLimitationsTraverser::error(TSourceLoc loc, const char *reason, const char *token)
+{
+ mDiagnostics->error(loc, reason, token);
+}
+
+void ValidateLimitationsTraverser::error(TSourceLoc loc,
+ const char *reason,
+ const ImmutableString &token)
+{
+ error(loc, reason, token.data());
+}
+
+bool ValidateLimitationsTraverser::isLoopIndex(TIntermSymbol *symbol)
+{
+ return std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(), symbol->uniqueId().get()) !=
+ mLoopSymbolIds.end();
+}
+
+bool ValidateLimitationsTraverser::validateLoopType(TIntermLoop *node)
+{
+ TLoopType type = node->getType();
+ if (type == ELoopFor)
+ return true;
+
+ // Reject while and do-while loops.
+ error(node->getLine(), "This type of loop is not allowed", type == ELoopWhile ? "while" : "do");
+ return false;
+}
+
+bool ValidateLimitationsTraverser::validateForLoopHeader(TIntermLoop *node)
+{
+ ASSERT(node->getType() == ELoopFor);
+
+ //
+ // The for statement has the form:
+ // for ( init-declaration ; condition ; expression ) statement
+ //
+ int indexSymbolId = validateForLoopInit(node);
+ if (indexSymbolId < 0)
+ return false;
+ if (!validateForLoopCond(node, indexSymbolId))
+ return false;
+ if (!validateForLoopExpr(node, indexSymbolId))
+ return false;
+
+ return true;
+}
+
+int ValidateLimitationsTraverser::validateForLoopInit(TIntermLoop *node)
+{
+ TIntermNode *init = node->getInit();
+ if (init == nullptr)
+ {
+ error(node->getLine(), "Missing init declaration", "for");
+ return -1;
+ }
+
+ //
+ // init-declaration has the form:
+ // type-specifier identifier = constant-expression
+ //
+ TIntermDeclaration *decl = init->getAsDeclarationNode();
+ if (decl == nullptr)
+ {
+ error(init->getLine(), "Invalid init declaration", "for");
+ return -1;
+ }
+ // To keep things simple do not allow declaration list.
+ TIntermSequence *declSeq = decl->getSequence();
+ if (declSeq->size() != 1)
+ {
+ error(decl->getLine(), "Invalid init declaration", "for");
+ return -1;
+ }
+ TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode();
+ if ((declInit == nullptr) || (declInit->getOp() != EOpInitialize))
+ {
+ error(decl->getLine(), "Invalid init declaration", "for");
+ return -1;
+ }
+ TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ error(declInit->getLine(), "Invalid init declaration", "for");
+ return -1;
+ }
+ // The loop index has type int or float.
+ TBasicType type = symbol->getBasicType();
+ if ((type != EbtInt) && (type != EbtUInt) && (type != EbtFloat))
+ {
+ error(symbol->getLine(), "Invalid type for loop index", getBasicString(type));
+ return -1;
+ }
+ // The loop index is initialized with constant expression.
+ if (!isConstExpr(declInit->getRight()))
+ {
+ error(declInit->getLine(), "Loop index cannot be initialized with non-constant expression",
+ symbol->getName());
+ return -1;
+ }
+
+ return symbol->uniqueId().get();
+}
+
+bool ValidateLimitationsTraverser::validateForLoopCond(TIntermLoop *node, int indexSymbolId)
+{
+ TIntermNode *cond = node->getCondition();
+ if (cond == nullptr)
+ {
+ error(node->getLine(), "Missing condition", "for");
+ return false;
+ }
+ //
+ // condition has the form:
+ // loop_index relational_operator constant_expression
+ //
+ TIntermBinary *binOp = cond->getAsBinaryNode();
+ if (binOp == nullptr)
+ {
+ error(node->getLine(), "Invalid condition", "for");
+ return false;
+ }
+ // Loop index should be to the left of relational operator.
+ TIntermSymbol *symbol = binOp->getLeft()->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ error(binOp->getLine(), "Invalid condition", "for");
+ return false;
+ }
+ if (symbol->uniqueId().get() != indexSymbolId)
+ {
+ error(symbol->getLine(), "Expected loop index", symbol->getName());
+ return false;
+ }
+ // Relational operator is one of: > >= < <= == or !=.
+ switch (binOp->getOp())
+ {
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ break;
+ default:
+ error(binOp->getLine(), "Invalid relational operator",
+ GetOperatorString(binOp->getOp()));
+ break;
+ }
+ // Loop index must be compared with a constant.
+ if (!isConstExpr(binOp->getRight()))
+ {
+ error(binOp->getLine(), "Loop index cannot be compared with non-constant expression",
+ symbol->getName());
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLimitationsTraverser::validateForLoopExpr(TIntermLoop *node, int indexSymbolId)
+{
+ TIntermNode *expr = node->getExpression();
+ if (expr == nullptr)
+ {
+ error(node->getLine(), "Missing expression", "for");
+ return false;
+ }
+
+ // for expression has one of the following forms:
+ // loop_index++
+ // loop_index--
+ // loop_index += constant_expression
+ // loop_index -= constant_expression
+ // ++loop_index
+ // --loop_index
+ // The last two forms are not specified in the spec, but I am assuming
+ // its an oversight.
+ TIntermUnary *unOp = expr->getAsUnaryNode();
+ TIntermBinary *binOp = unOp ? nullptr : expr->getAsBinaryNode();
+
+ TOperator op = EOpNull;
+ const TFunction *opFunc = nullptr;
+ TIntermSymbol *symbol = nullptr;
+ if (unOp != nullptr)
+ {
+ op = unOp->getOp();
+ opFunc = unOp->getFunction();
+ symbol = unOp->getOperand()->getAsSymbolNode();
+ }
+ else if (binOp != nullptr)
+ {
+ op = binOp->getOp();
+ symbol = binOp->getLeft()->getAsSymbolNode();
+ }
+
+ // The operand must be loop index.
+ if (symbol == nullptr)
+ {
+ error(expr->getLine(), "Invalid expression", "for");
+ return false;
+ }
+ if (symbol->uniqueId().get() != indexSymbolId)
+ {
+ error(symbol->getLine(), "Expected loop index", symbol->getName());
+ return false;
+ }
+
+ // The operator is one of: ++ -- += -=.
+ switch (op)
+ {
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+ ASSERT((unOp != nullptr) && (binOp == nullptr));
+ break;
+ case EOpAddAssign:
+ case EOpSubAssign:
+ ASSERT((unOp == nullptr) && (binOp != nullptr));
+ break;
+ default:
+ if (BuiltInGroup::IsBuiltIn(op))
+ {
+ ASSERT(opFunc != nullptr);
+ error(expr->getLine(), "Invalid built-in call", opFunc->name().data());
+ }
+ else
+ {
+ error(expr->getLine(), "Invalid operator", GetOperatorString(op));
+ }
+ return false;
+ }
+
+ // Loop index must be incremented/decremented with a constant.
+ if (binOp != nullptr)
+ {
+ if (!isConstExpr(binOp->getRight()))
+ {
+ error(binOp->getLine(), "Loop index cannot be modified by non-constant expression",
+ symbol->getName());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateLimitationsTraverser::isConstExpr(TIntermNode *node)
+{
+ ASSERT(node != nullptr);
+ return node->getAsConstantUnion() != nullptr && node->getAsTyped()->getQualifier() == EvqConst;
+}
+
+bool ValidateLimitationsTraverser::isConstIndexExpr(TIntermNode *node)
+{
+ ASSERT(node != nullptr);
+
+ ValidateConstIndexExpr validate(mLoopSymbolIds);
+ node->traverse(&validate);
+ return validate.isValid();
+}
+
+bool ValidateLimitationsTraverser::validateIndexing(TIntermBinary *node)
+{
+ ASSERT((node->getOp() == EOpIndexDirect) || (node->getOp() == EOpIndexIndirect));
+
+ bool valid = true;
+ TIntermTyped *index = node->getRight();
+ // The index expession must be a constant-index-expression unless
+ // the operand is a uniform in a vertex shader.
+ TIntermTyped *operand = node->getLeft();
+ bool skip = (mShaderType == GL_VERTEX_SHADER) && (operand->getQualifier() == EvqUniform);
+ if (!skip && !isConstIndexExpr(index))
+ {
+ error(index->getLine(), "Index expression must be constant", "[]");
+ valid = false;
+ }
+ return valid;
+}
+
+} // namespace
+
+bool ValidateLimitations(TIntermNode *root,
+ GLenum shaderType,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics)
+{
+ ValidateLimitationsTraverser validate(shaderType, symbolTable, diagnostics);
+ root->traverse(&validate);
+ return diagnostics->numErrors() == 0;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.h b/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.h
new file mode 100644
index 0000000000..00f26b53f5
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.h
@@ -0,0 +1,26 @@
+//
+// Copyright 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_
+#define COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_
+
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+class TDiagnostics;
+
+// Returns true if the given shader does not exceed the minimum functionality mandated in GLSL ES
+// 1.00 spec Appendix A.
+bool ValidateLimitations(TIntermNode *root,
+ GLenum shaderType,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp
new file mode 100644
index 0000000000..b3f53e27fa
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp
@@ -0,0 +1,30 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ValidateMaxParameters checks if function definitions have more than a set number of parameters.
+
+#include "compiler/translator/ValidateMaxParameters.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+
+namespace sh
+{
+
+bool ValidateMaxParameters(TIntermBlock *root, unsigned int maxParameters)
+{
+ for (TIntermNode *node : *root->getSequence())
+ {
+ TIntermFunctionDefinition *definition = node->getAsFunctionDefinition();
+ if (definition != nullptr &&
+ definition->getFunctionPrototype()->getFunction()->getParamCount() > maxParameters)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.h b/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.h
new file mode 100644
index 0000000000..73cdb992d3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.h
@@ -0,0 +1,21 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ValidateMaxParameters checks if function definitions have more than a set number of parameters.
+
+#ifndef COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_
+#define COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_
+
+namespace sh
+{
+
+class TIntermBlock;
+
+// Return true if valid.
+bool ValidateMaxParameters(TIntermBlock *root, unsigned int maxParameters);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp
new file mode 100644
index 0000000000..5ba70c4de1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp
@@ -0,0 +1,184 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations,
+// out-of-range locations, that locations are specified when using multiple outputs, and YUV output
+// validity.
+
+#include "compiler/translator/ValidateOutputs.h"
+
+#include <set>
+
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/ParseContext.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
+{
+ diagnostics->error(symbol.getLine(), reason, symbol.getName().data());
+}
+
+class ValidateOutputsTraverser : public TIntermTraverser
+{
+ public:
+ ValidateOutputsTraverser(const TExtensionBehavior &extBehavior, int maxDrawBuffers);
+
+ void validate(TDiagnostics *diagnostics) const;
+
+ void visitSymbol(TIntermSymbol *) override;
+
+ private:
+ int mMaxDrawBuffers;
+ bool mAllowUnspecifiedOutputLocationResolution;
+ bool mUsesFragDepth;
+
+ typedef std::vector<TIntermSymbol *> OutputVector;
+ OutputVector mOutputs;
+ OutputVector mUnspecifiedLocationOutputs;
+ OutputVector mYuvOutputs;
+ std::set<int> mVisitedSymbols; // Visited symbol ids.
+};
+
+ValidateOutputsTraverser::ValidateOutputsTraverser(const TExtensionBehavior &extBehavior,
+ int maxDrawBuffers)
+ : TIntermTraverser(true, false, false),
+ mMaxDrawBuffers(maxDrawBuffers),
+ mAllowUnspecifiedOutputLocationResolution(
+ IsExtensionEnabled(extBehavior, TExtension::EXT_blend_func_extended)),
+ mUsesFragDepth(false)
+{}
+
+void ValidateOutputsTraverser::visitSymbol(TIntermSymbol *symbol)
+{
+ if (symbol->variable().symbolType() == SymbolType::Empty)
+ return;
+
+ if (mVisitedSymbols.count(symbol->uniqueId().get()) == 1)
+ return;
+
+ mVisitedSymbols.insert(symbol->uniqueId().get());
+
+ TQualifier qualifier = symbol->getQualifier();
+ if (qualifier == EvqFragmentOut)
+ {
+ if (symbol->getType().getLayoutQualifier().location != -1)
+ {
+ mOutputs.push_back(symbol);
+ }
+ else if (symbol->getType().getLayoutQualifier().yuv == true)
+ {
+ mYuvOutputs.push_back(symbol);
+ }
+ else
+ {
+ mUnspecifiedLocationOutputs.push_back(symbol);
+ }
+ }
+ else if (qualifier == EvqFragDepth)
+ {
+ mUsesFragDepth = true;
+ }
+}
+
+void ValidateOutputsTraverser::validate(TDiagnostics *diagnostics) const
+{
+ ASSERT(diagnostics);
+ OutputVector validOutputs(mMaxDrawBuffers, nullptr);
+ OutputVector validSecondaryOutputs(mMaxDrawBuffers, nullptr);
+
+ for (const auto &symbol : mOutputs)
+ {
+ const TType &type = symbol->getType();
+ ASSERT(!type.isArrayOfArrays()); // Disallowed in GLSL ES 3.10 section 4.3.6.
+ const size_t elementCount =
+ static_cast<size_t>(type.isArray() ? type.getOutermostArraySize() : 1u);
+ const size_t location = static_cast<size_t>(type.getLayoutQualifier().location);
+
+ ASSERT(type.getLayoutQualifier().location != -1);
+
+ OutputVector *validOutputsToUse = &validOutputs;
+ // The default index is 0, so we only assign the output to secondary outputs in case the
+ // index is explicitly set to 1.
+ if (type.getLayoutQualifier().index == 1)
+ {
+ validOutputsToUse = &validSecondaryOutputs;
+ }
+
+ if (location + elementCount <= validOutputsToUse->size())
+ {
+ for (size_t elementIndex = 0; elementIndex < elementCount; elementIndex++)
+ {
+ const size_t offsetLocation = location + elementIndex;
+ if ((*validOutputsToUse)[offsetLocation])
+ {
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
+ strstr << "conflicting output locations with previously defined output '"
+ << (*validOutputsToUse)[offsetLocation]->getName() << "'";
+ error(*symbol, strstr.str().c_str(), diagnostics);
+ }
+ else
+ {
+ (*validOutputsToUse)[offsetLocation] = symbol;
+ }
+ }
+ }
+ else
+ {
+ if (elementCount > 0)
+ {
+ error(*symbol,
+ elementCount > 1 ? "output array locations would exceed MAX_DRAW_BUFFERS"
+ : "output location must be < MAX_DRAW_BUFFERS",
+ diagnostics);
+ }
+ }
+ }
+
+ if (!mAllowUnspecifiedOutputLocationResolution &&
+ ((!mOutputs.empty() && !mUnspecifiedLocationOutputs.empty()) ||
+ mUnspecifiedLocationOutputs.size() > 1))
+ {
+ for (const auto &symbol : mUnspecifiedLocationOutputs)
+ {
+ error(*symbol,
+ "must explicitly specify all locations when using multiple fragment outputs",
+ diagnostics);
+ }
+ }
+
+ if (!mYuvOutputs.empty() && (mYuvOutputs.size() > 1 || mUsesFragDepth || !mOutputs.empty() ||
+ !mUnspecifiedLocationOutputs.empty()))
+ {
+ for (const auto &symbol : mYuvOutputs)
+ {
+ error(*symbol,
+ "not allowed to specify yuv qualifier when using depth or multiple color "
+ "fragment outputs",
+ diagnostics);
+ }
+ }
+}
+
+} // anonymous namespace
+
+bool ValidateOutputs(TIntermBlock *root,
+ const TExtensionBehavior &extBehavior,
+ int maxDrawBuffers,
+ TDiagnostics *diagnostics)
+{
+ ValidateOutputsTraverser validateOutputs(extBehavior, maxDrawBuffers);
+ root->traverse(&validateOutputs);
+ int numErrorsBefore = diagnostics->numErrors();
+ validateOutputs.validate(diagnostics);
+ return (diagnostics->numErrors() == numErrorsBefore);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.h b/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.h
new file mode 100644
index 0000000000..136288bb50
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations,
+// out-of-range locations, that locations are specified when using multiple outputs, and YUV output
+// validity.
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
+#define COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
+
+#include "compiler/translator/ExtensionBehavior.h"
+
+namespace sh
+{
+
+class TIntermBlock;
+class TDiagnostics;
+
+// Returns true if the shader has no conflicting or otherwise erroneous fragment outputs.
+bool ValidateOutputs(TIntermBlock *root,
+ const TExtensionBehavior &extBehavior,
+ int maxDrawBuffers,
+ TDiagnostics *diagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp
new file mode 100644
index 0000000000..8a9e7b22a1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp
@@ -0,0 +1,315 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/ValidateSwitch.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+const int kMaxAllowedTraversalDepth = 256;
+
+class ValidateSwitch : public TIntermTraverser
+{
+ public:
+ static bool validate(TBasicType switchType,
+ TDiagnostics *diagnostics,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc);
+
+ void visitSymbol(TIntermSymbol *) override;
+ void visitConstantUnion(TIntermConstantUnion *) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *) override;
+ bool visitBlock(Visit visit, TIntermBlock *) override;
+ bool visitBinary(Visit, TIntermBinary *) override;
+ bool visitUnary(Visit, TIntermUnary *) override;
+ bool visitTernary(Visit, TIntermTernary *) override;
+ bool visitSwizzle(Visit, TIntermSwizzle *) override;
+ bool visitIfElse(Visit visit, TIntermIfElse *) override;
+ bool visitSwitch(Visit, TIntermSwitch *) override;
+ bool visitCase(Visit, TIntermCase *node) override;
+ bool visitAggregate(Visit, TIntermAggregate *) override;
+ bool visitLoop(Visit visit, TIntermLoop *) override;
+ bool visitBranch(Visit, TIntermBranch *) override;
+
+ private:
+ ValidateSwitch(TBasicType switchType, TDiagnostics *context);
+
+ bool validateInternal(const TSourceLoc &loc);
+
+ TBasicType mSwitchType;
+ TDiagnostics *mDiagnostics;
+ bool mCaseTypeMismatch;
+ bool mFirstCaseFound;
+ bool mStatementBeforeCase;
+ bool mLastStatementWasCase;
+ int mControlFlowDepth;
+ bool mCaseInsideControlFlow;
+ int mDefaultCount;
+ std::set<int> mCasesSigned;
+ std::set<unsigned int> mCasesUnsigned;
+ bool mDuplicateCases;
+};
+
+bool ValidateSwitch::validate(TBasicType switchType,
+ TDiagnostics *diagnostics,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc)
+{
+ ValidateSwitch validate(switchType, diagnostics);
+ ASSERT(statementList);
+ statementList->traverse(&validate);
+ return validate.validateInternal(loc);
+}
+
+ValidateSwitch::ValidateSwitch(TBasicType switchType, TDiagnostics *diagnostics)
+ : TIntermTraverser(true, false, true, nullptr),
+ mSwitchType(switchType),
+ mDiagnostics(diagnostics),
+ mCaseTypeMismatch(false),
+ mFirstCaseFound(false),
+ mStatementBeforeCase(false),
+ mLastStatementWasCase(false),
+ mControlFlowDepth(0),
+ mCaseInsideControlFlow(false),
+ mDefaultCount(0),
+ mDuplicateCases(false)
+{
+ setMaxAllowedDepth(kMaxAllowedTraversalDepth);
+}
+
+void ValidateSwitch::visitSymbol(TIntermSymbol *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+}
+
+void ValidateSwitch::visitConstantUnion(TIntermConstantUnion *)
+{
+ // Conditions of case labels are not traversed, so this is some other constant
+ // Could be just a statement like "0;"
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+}
+
+bool ValidateSwitch::visitDeclaration(Visit, TIntermDeclaration *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::visitBlock(Visit visit, TIntermBlock *)
+{
+ if (getParentNode() != nullptr)
+ {
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ if (visit == PreVisit)
+ ++mControlFlowDepth;
+ if (visit == PostVisit)
+ --mControlFlowDepth;
+ }
+ return true;
+}
+
+bool ValidateSwitch::visitBinary(Visit, TIntermBinary *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::visitUnary(Visit, TIntermUnary *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::visitTernary(Visit, TIntermTernary *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::visitSwizzle(Visit, TIntermSwizzle *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::visitIfElse(Visit visit, TIntermIfElse *)
+{
+ if (visit == PreVisit)
+ ++mControlFlowDepth;
+ if (visit == PostVisit)
+ --mControlFlowDepth;
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::visitSwitch(Visit, TIntermSwitch *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ // Don't go into nested switch statements
+ return false;
+}
+
+bool ValidateSwitch::visitCase(Visit, TIntermCase *node)
+{
+ const char *nodeStr = node->hasCondition() ? "case" : "default";
+ if (mControlFlowDepth > 0)
+ {
+ mDiagnostics->error(node->getLine(), "label statement nested inside control flow", nodeStr);
+ mCaseInsideControlFlow = true;
+ }
+ mFirstCaseFound = true;
+ mLastStatementWasCase = true;
+ if (!node->hasCondition())
+ {
+ ++mDefaultCount;
+ if (mDefaultCount > 1)
+ {
+ mDiagnostics->error(node->getLine(), "duplicate default label", nodeStr);
+ }
+ }
+ else
+ {
+ TIntermConstantUnion *condition = node->getCondition()->getAsConstantUnion();
+ if (condition == nullptr)
+ {
+ // This can happen in error cases.
+ return false;
+ }
+ TBasicType conditionType = condition->getBasicType();
+ if (conditionType != mSwitchType)
+ {
+ mDiagnostics->error(condition->getLine(),
+ "case label type does not match switch init-expression type",
+ nodeStr);
+ mCaseTypeMismatch = true;
+ }
+
+ if (conditionType == EbtInt)
+ {
+ int iConst = condition->getIConst(0);
+ if (mCasesSigned.find(iConst) != mCasesSigned.end())
+ {
+ mDiagnostics->error(condition->getLine(), "duplicate case label", nodeStr);
+ mDuplicateCases = true;
+ }
+ else
+ {
+ mCasesSigned.insert(iConst);
+ }
+ }
+ else if (conditionType == EbtUInt)
+ {
+ unsigned int uConst = condition->getUConst(0);
+ if (mCasesUnsigned.find(uConst) != mCasesUnsigned.end())
+ {
+ mDiagnostics->error(condition->getLine(), "duplicate case label", nodeStr);
+ mDuplicateCases = true;
+ }
+ else
+ {
+ mCasesUnsigned.insert(uConst);
+ }
+ }
+ // Other types are possible only in error cases, where the error has already been generated
+ // when parsing the case statement.
+ }
+ // Don't traverse the condition of the case statement
+ return false;
+}
+
+bool ValidateSwitch::visitAggregate(Visit visit, TIntermAggregate *)
+{
+ if (getParentNode() != nullptr)
+ {
+ // This is not the statementList node, but some other node.
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ }
+ return true;
+}
+
+bool ValidateSwitch::visitLoop(Visit visit, TIntermLoop *)
+{
+ if (visit == PreVisit)
+ ++mControlFlowDepth;
+ if (visit == PostVisit)
+ --mControlFlowDepth;
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::visitBranch(Visit, TIntermBranch *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::validateInternal(const TSourceLoc &loc)
+{
+ if (mStatementBeforeCase)
+ {
+ mDiagnostics->error(loc, "statement before the first label", "switch");
+ }
+ if (mLastStatementWasCase)
+ {
+ // There have been some differences between versions of GLSL ES specs on whether this should
+ // be an error or not, but as of early 2018 the latest discussion is that this is an error
+ // also on GLSL ES versions newer than 3.00.
+ mDiagnostics->error(
+ loc, "no statement between the last label and the end of the switch statement",
+ "switch");
+ }
+ if (getMaxDepth() >= kMaxAllowedTraversalDepth)
+ {
+ mDiagnostics->error(loc, "too complex expressions inside a switch statement", "switch");
+ }
+ return !mStatementBeforeCase && !mLastStatementWasCase && !mCaseInsideControlFlow &&
+ !mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases &&
+ getMaxDepth() < kMaxAllowedTraversalDepth;
+}
+
+} // anonymous namespace
+
+bool ValidateSwitchStatementList(TBasicType switchType,
+ TDiagnostics *diagnostics,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc)
+{
+ return ValidateSwitch::validate(switchType, diagnostics, statementList, loc);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h b/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h
new file mode 100644
index 0000000000..828faac98a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATESWITCH_H_
+#define COMPILER_TRANSLATOR_VALIDATESWITCH_H_
+
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+class TDiagnostics;
+class TIntermBlock;
+
+// Check for errors and output error messages on the context.
+// Returns true if there are no errors.
+bool ValidateSwitchStatementList(TBasicType switchType,
+ TDiagnostics *diagnostics,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATESWITCH_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.cpp
new file mode 100644
index 0000000000..6097b6d236
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.cpp
@@ -0,0 +1,229 @@
+//
+// Copyright 2021 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/ValidateTypeSizeLimitations.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/blocklayout.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Arbitrarily enforce that all types declared with a size in bytes of over 2 GB will cause
+// compilation failure.
+//
+// For local and global variables, the limit is much lower (1MB) as that much memory won't fit in
+// the GPU registers anyway.
+constexpr size_t kMaxVariableSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
+constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(1) * 1024 * 1024;
+
+// Traverses intermediate tree to ensure that the shader does not
+// exceed certain implementation-defined limits on the sizes of types.
+// Some code was copied from the CollectVariables pass.
+class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
+{
+ public:
+ ValidateTypeSizeLimitationsTraverser(TSymbolTable *symbolTable, TDiagnostics *diagnostics)
+ : TIntermTraverser(true, false, false, symbolTable), mDiagnostics(diagnostics)
+ {
+ ASSERT(diagnostics);
+ }
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ for (TIntermNode *variableNode : sequence)
+ {
+ // See CollectVariablesTraverser::visitDeclaration for a
+ // deeper analysis of the AST structures that might be
+ // encountered.
+ TIntermSymbol *asSymbol = variableNode->getAsSymbolNode();
+ TIntermBinary *asBinary = variableNode->getAsBinaryNode();
+
+ if (asBinary != nullptr)
+ {
+ ASSERT(asBinary->getOp() == EOpInitialize);
+ asSymbol = asBinary->getLeft()->getAsSymbolNode();
+ }
+
+ ASSERT(asSymbol);
+
+ const TVariable &variable = asSymbol->variable();
+ if (variable.symbolType() == SymbolType::AngleInternal)
+ {
+ // Ignore internal variables.
+ continue;
+ }
+
+ const TType &variableType = asSymbol->getType();
+
+ // Create a ShaderVariable from which to compute
+ // (conservative) sizing information.
+ ShaderVariable shaderVar;
+ setCommonVariableProperties(variableType, variable, &shaderVar);
+
+ // Compute the std140 layout of this variable, assuming
+ // it's a member of a block (which it might not be).
+ Std140BlockEncoder layoutEncoder;
+ BlockEncoderVisitor visitor("", "", &layoutEncoder);
+ // Since the size limit's arbitrary, it doesn't matter
+ // whether the row-major layout is correctly determined.
+ bool isRowMajorLayout = false;
+ TraverseShaderVariable(shaderVar, isRowMajorLayout, &visitor);
+ if (layoutEncoder.getCurrentOffset() > kMaxVariableSizeInBytes)
+ {
+ error(asSymbol->getLine(),
+ "Size of declared variable exceeds implementation-defined limit",
+ asSymbol->getName());
+ return false;
+ }
+
+ const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
+ variableType.getQualifier() == EvqGlobal ||
+ variableType.getQualifier() == EvqConst;
+ if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes && isPrivate)
+ {
+ error(asSymbol->getLine(),
+ "Size of declared private variable exceeds implementation-defined limit",
+ asSymbol->getName());
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private:
+ void error(TSourceLoc loc, const char *reason, const ImmutableString &token)
+ {
+ mDiagnostics->error(loc, reason, token.data());
+ }
+
+ void setFieldOrVariableProperties(const TType &type,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ ShaderVariable *variableOut) const
+ {
+ ASSERT(variableOut);
+
+ variableOut->staticUse = staticUse;
+ variableOut->isShaderIOBlock = isShaderIOBlock;
+ variableOut->isPatch = isPatch;
+
+ const TStructure *structure = type.getStruct();
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ if (structure)
+ {
+ // Structures use a NONE type that isn't exposed outside ANGLE.
+ variableOut->type = GL_NONE;
+ if (structure->symbolType() != SymbolType::Empty)
+ {
+ variableOut->structOrBlockName = structure->name().data();
+ }
+
+ const TFieldList &fields = structure->fields();
+
+ for (const TField *field : fields)
+ {
+ // Regardless of the variable type (uniform, in/out etc.) its fields are always
+ // plain ShaderVariable objects.
+ ShaderVariable fieldVariable;
+ setFieldProperties(*field->type(), field->name(), staticUse, isShaderIOBlock,
+ isPatch, &fieldVariable);
+ variableOut->fields.push_back(fieldVariable);
+ }
+ }
+ else if (interfaceBlock && isShaderIOBlock)
+ {
+ variableOut->type = GL_NONE;
+ if (interfaceBlock->symbolType() != SymbolType::Empty)
+ {
+ variableOut->structOrBlockName = interfaceBlock->name().data();
+ }
+ const TFieldList &fields = interfaceBlock->fields();
+ for (const TField *field : fields)
+ {
+ ShaderVariable fieldVariable;
+ setFieldProperties(*field->type(), field->name(), staticUse, true, isPatch,
+ &fieldVariable);
+ fieldVariable.isShaderIOBlock = true;
+ variableOut->fields.push_back(fieldVariable);
+ }
+ }
+ else
+ {
+ variableOut->type = GLVariableType(type);
+ variableOut->precision = GLVariablePrecision(type);
+ }
+
+ const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
+ if (!arraySizes.empty())
+ {
+ variableOut->arraySizes.assign(arraySizes.begin(), arraySizes.end());
+ // WebGL does not support tessellation shaders; removed
+ // code specific to that shader type.
+ }
+ }
+
+ void setFieldProperties(const TType &type,
+ const ImmutableString &name,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ ShaderVariable *variableOut) const
+ {
+ ASSERT(variableOut);
+ setFieldOrVariableProperties(type, staticUse, isShaderIOBlock, isPatch, variableOut);
+ variableOut->name.assign(name.data(), name.length());
+ }
+
+ void setCommonVariableProperties(const TType &type,
+ const TVariable &variable,
+ ShaderVariable *variableOut) const
+ {
+ ASSERT(variableOut);
+
+ // Shortcut some processing that's unnecessary for this analysis.
+ const bool staticUse = true;
+ const bool isShaderIOBlock = type.getInterfaceBlock() != nullptr;
+ const bool isPatch = false;
+
+ setFieldOrVariableProperties(type, staticUse, isShaderIOBlock, isPatch, variableOut);
+
+ const bool isNamed = variable.symbolType() != SymbolType::Empty;
+
+ if (isNamed)
+ {
+ variableOut->name.assign(variable.name().data(), variable.name().length());
+ }
+ }
+
+ TDiagnostics *mDiagnostics;
+ std::vector<int> mLoopSymbolIds;
+};
+
+} // namespace
+
+bool ValidateTypeSizeLimitations(TIntermNode *root,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics)
+{
+ ValidateTypeSizeLimitationsTraverser validate(symbolTable, diagnostics);
+ root->traverse(&validate);
+ return diagnostics->numErrors() == 0;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.h b/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.h
new file mode 100644
index 0000000000..defa39876d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2021 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATETYPESIZELIMITATIONS_H_
+#define COMPILER_TRANSLATOR_VALIDATETYPESIZELIMITATIONS_H_
+
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+class TDiagnostics;
+
+// Returns true if the given shader does not violate certain
+// implementation-defined limits on the size of variables' types.
+bool ValidateTypeSizeLimitations(TIntermNode *root,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATETYPESIZELIMITATIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp
new file mode 100644
index 0000000000..3c2eeeb5bc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp
@@ -0,0 +1,368 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The ValidateVaryingLocations function checks if there exists location conflicts on shader
+// varyings.
+//
+
+#include "ValidateVaryingLocations.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
+{
+ diagnostics->error(symbol.getLine(), reason, symbol.getName().data());
+}
+
+int GetStructLocationCount(const TStructure *structure);
+
+int GetFieldLocationCount(const TField *field)
+{
+ int field_size = 0;
+ const TType *fieldType = field->type();
+
+ if (fieldType->getStruct() != nullptr)
+ {
+ field_size = GetStructLocationCount(fieldType->getStruct());
+ }
+ else if (fieldType->isMatrix())
+ {
+ field_size = fieldType->getNominalSize();
+ }
+ else
+ {
+ ASSERT(fieldType->getSecondarySize() == 1);
+ field_size = 1;
+ }
+
+ if (fieldType->isArray())
+ {
+ field_size *= fieldType->getArraySizeProduct();
+ }
+
+ return field_size;
+}
+
+int GetStructLocationCount(const TStructure *structure)
+{
+ int totalLocation = 0;
+ for (const TField *field : structure->fields())
+ {
+ totalLocation += GetFieldLocationCount(field);
+ }
+ return totalLocation;
+}
+
+int GetInterfaceBlockLocationCount(const TType &varyingType, bool ignoreVaryingArraySize)
+{
+ int totalLocation = 0;
+ for (const TField *field : varyingType.getInterfaceBlock()->fields())
+ {
+ totalLocation += GetFieldLocationCount(field);
+ }
+
+ if (!ignoreVaryingArraySize && varyingType.isArray())
+ {
+ totalLocation *= varyingType.getArraySizeProduct();
+ }
+ return totalLocation;
+}
+
+int GetLocationCount(const TType &varyingType, bool ignoreVaryingArraySize)
+{
+ ASSERT(!varyingType.isInterfaceBlock());
+
+ if (varyingType.getStruct() != nullptr)
+ {
+ int totalLocation = 0;
+ for (const TField *field : varyingType.getStruct()->fields())
+ {
+ const TType *fieldType = field->type();
+ ASSERT(fieldType->getStruct() == nullptr && !fieldType->isArray());
+
+ totalLocation += GetFieldLocationCount(field);
+ }
+ return totalLocation;
+ }
+
+ ASSERT(varyingType.isMatrix() || varyingType.getSecondarySize() == 1);
+ int elementLocationCount = varyingType.isMatrix() ? varyingType.getNominalSize() : 1;
+
+ // [GL_EXT_shader_io_blocks SPEC Chapter 4.4.1]
+ // Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation
+ // evaluation inputs all have an additional level of arrayness relative to other shader inputs
+ // and outputs. This outer array level is removed from the type before considering how many
+ // locations the type consumes.
+ if (ignoreVaryingArraySize)
+ {
+ // Array-of-arrays cannot be inputs or outputs of a geometry shader.
+ // (GL_EXT_geometry_shader SPEC issues(5))
+ ASSERT(!varyingType.isArrayOfArrays());
+ return elementLocationCount;
+ }
+
+ return elementLocationCount * varyingType.getArraySizeProduct();
+}
+
+bool ShouldIgnoreVaryingArraySize(TQualifier qualifier, GLenum shaderType)
+{
+ bool isVaryingIn = IsShaderIn(qualifier) && qualifier != EvqPatchIn;
+
+ switch (shaderType)
+ {
+ case GL_GEOMETRY_SHADER:
+ case GL_TESS_EVALUATION_SHADER:
+ return isVaryingIn;
+ case GL_TESS_CONTROL_SHADER:
+ return (IsShaderOut(qualifier) && qualifier != EvqPatchOut) || isVaryingIn;
+ default:
+ return false;
+ }
+}
+
+struct SymbolAndField
+{
+ const TIntermSymbol *symbol;
+ const TField *field;
+};
+using LocationMap = std::map<int, SymbolAndField>;
+
+void MarkVaryingLocations(TDiagnostics *diagnostics,
+ const TIntermSymbol *varying,
+ const TField *field,
+ int location,
+ int elementCount,
+ LocationMap *locationMap)
+{
+ for (int elementIndex = 0; elementIndex < elementCount; ++elementIndex)
+ {
+ const int offsetLocation = location + elementIndex;
+ auto conflict = locationMap->find(offsetLocation);
+ if (conflict != locationMap->end())
+ {
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
+ strstr << "'" << varying->getName();
+ if (field)
+ {
+ strstr << "." << field->name();
+ }
+ strstr << "' conflicting location with '" << conflict->second.symbol->getName();
+ if (conflict->second.field)
+ {
+ strstr << "." << conflict->second.field->name();
+ }
+ strstr << "'";
+ error(*varying, strstr.str().c_str(), diagnostics);
+ }
+ else
+ {
+ (*locationMap)[offsetLocation] = {varying, field};
+ }
+ }
+}
+
+using VaryingVector = std::vector<const TIntermSymbol *>;
+
+void ValidateShaderInterfaceAndAssignLocations(TDiagnostics *diagnostics,
+ const VaryingVector &varyingVector,
+ GLenum shaderType)
+{
+ // Location conflicts can only happen when there are two or more varyings in varyingVector.
+ if (varyingVector.size() <= 1)
+ {
+ return;
+ }
+
+ LocationMap locationMap;
+ for (const TIntermSymbol *varying : varyingVector)
+ {
+ const TType &varyingType = varying->getType();
+ const int location = varyingType.getLayoutQualifier().location;
+ ASSERT(location >= 0);
+
+ bool ignoreVaryingArraySize =
+ ShouldIgnoreVaryingArraySize(varying->getQualifier(), shaderType);
+
+ // A varying is either:
+ //
+ // - A vector or matrix, which can take a number of contiguous locations
+ // - A struct, which also takes a number of contiguous locations
+ // - An interface block.
+ //
+ // Interface blocks can assign arbitrary locations to their fields, for example:
+ //
+ // layout(location = 4) in block {
+ // vec4 a; // gets location 4
+ // vec4 b; // gets location 5
+ // layout(location = 7) vec4 c; // gets location 7
+ // vec4 d; // gets location 8
+ // layout (location = 1) vec4 e; // gets location 1
+ // vec4 f; // gets location 2
+ // };
+ //
+ // The following code therefore takes two paths. For non-interface-block types, the number
+ // of locations for the varying is calculated (elementCount), and all locations in
+ // [location, location + elementCount) are marked as occupied.
+ //
+ // For interface blocks, a similar algorithm is implemented except each field is
+ // individually marked with the location either advancing automatically or taking its value
+ // from the field's layout qualifier.
+
+ if (varyingType.isInterfaceBlock())
+ {
+ int currentLocation = location;
+ bool anyFieldWithLocation = false;
+
+ for (const TField *field : varyingType.getInterfaceBlock()->fields())
+ {
+ const int fieldLocation = field->type()->getLayoutQualifier().location;
+ if (fieldLocation >= 0)
+ {
+ currentLocation = fieldLocation;
+ anyFieldWithLocation = true;
+ }
+
+ const int fieldLocationCount = GetFieldLocationCount(field);
+ MarkVaryingLocations(diagnostics, varying, field, currentLocation,
+ fieldLocationCount, &locationMap);
+
+ currentLocation += fieldLocationCount;
+ }
+
+ // Array interface blocks can't have location qualifiers on fields.
+ ASSERT(ignoreVaryingArraySize || !anyFieldWithLocation || !varyingType.isArray());
+
+ if (!ignoreVaryingArraySize && varyingType.isArray())
+ {
+ // This is only reached if the varying is an array of interface blocks, with only a
+ // layout qualifier on the block itself, for example:
+ //
+ // layout(location = 4) in block {
+ // vec4 a;
+ // vec4 b;
+ // vec4 c;
+ // vec4 d;
+ // } instance[N];
+ //
+ // The locations for instance[0] are already marked by the above code, so we need to
+ // further mark locations occupied by instances [1, N). |currentLocation| is
+ // already just past the end of instance[0], which is the beginning of instance[1].
+ //
+ int remainingLocations = currentLocation * (varyingType.getArraySizeProduct() - 1);
+ MarkVaryingLocations(diagnostics, varying, nullptr, currentLocation,
+ remainingLocations, &locationMap);
+ }
+ }
+ else
+ {
+ const int elementCount = GetLocationCount(varying->getType(), ignoreVaryingArraySize);
+ MarkVaryingLocations(diagnostics, varying, nullptr, location, elementCount,
+ &locationMap);
+ }
+ }
+}
+
+class ValidateVaryingLocationsTraverser : public TIntermTraverser
+{
+ public:
+ ValidateVaryingLocationsTraverser(GLenum shaderType);
+ void validate(TDiagnostics *diagnostics);
+
+ private:
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+
+ VaryingVector mInputVaryingsWithLocation;
+ VaryingVector mOutputVaryingsWithLocation;
+ GLenum mShaderType;
+};
+
+ValidateVaryingLocationsTraverser::ValidateVaryingLocationsTraverser(GLenum shaderType)
+ : TIntermTraverser(true, false, false), mShaderType(shaderType)
+{}
+
+bool ValidateVaryingLocationsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+ ASSERT(!sequence.empty());
+
+ const TIntermSymbol *symbol = sequence.front()->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ return false;
+ }
+
+ if (symbol->variable().symbolType() == SymbolType::Empty)
+ {
+ return false;
+ }
+
+ // Collect varyings that have explicit 'location' qualifiers.
+ const TQualifier qualifier = symbol->getQualifier();
+ if (symbol->getType().getLayoutQualifier().location != -1)
+ {
+ if (IsVaryingIn(qualifier))
+ {
+ mInputVaryingsWithLocation.push_back(symbol);
+ }
+ else if (IsVaryingOut(qualifier))
+ {
+ mOutputVaryingsWithLocation.push_back(symbol);
+ }
+ }
+
+ return false;
+}
+
+bool ValidateVaryingLocationsTraverser::visitFunctionDefinition(Visit visit,
+ TIntermFunctionDefinition *node)
+{
+ // We stop traversing function definitions because varyings cannot be defined in a function.
+ return false;
+}
+
+void ValidateVaryingLocationsTraverser::validate(TDiagnostics *diagnostics)
+{
+ ASSERT(diagnostics);
+
+ ValidateShaderInterfaceAndAssignLocations(diagnostics, mInputVaryingsWithLocation, mShaderType);
+ ValidateShaderInterfaceAndAssignLocations(diagnostics, mOutputVaryingsWithLocation,
+ mShaderType);
+}
+
+} // anonymous namespace
+
+unsigned int CalculateVaryingLocationCount(const TType &varyingType, GLenum shaderType)
+{
+ const TQualifier qualifier = varyingType.getQualifier();
+ const bool ignoreVaryingArraySize = ShouldIgnoreVaryingArraySize(qualifier, shaderType);
+
+ if (varyingType.isInterfaceBlock())
+ {
+ return GetInterfaceBlockLocationCount(varyingType, ignoreVaryingArraySize);
+ }
+
+ return GetLocationCount(varyingType, ignoreVaryingArraySize);
+}
+
+bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics, GLenum shaderType)
+{
+ ValidateVaryingLocationsTraverser varyingValidator(shaderType);
+ root->traverse(&varyingValidator);
+ int numErrorsBefore = diagnostics->numErrors();
+ varyingValidator.validate(diagnostics);
+ return (diagnostics->numErrors() == numErrorsBefore);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.h b/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.h
new file mode 100644
index 0000000000..5ce43c91c4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The ValidateVaryingLocations function checks if there exists location conflicts on shader
+// varyings.
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATEVARYINGLOCATIONS_H_
+#define COMPILER_TRANSLATOR_VALIDATEVARYINGLOCATIONS_H_
+
+#include "GLSLANG/ShaderVars.h"
+
+namespace sh
+{
+
+class TIntermBlock;
+class TIntermSymbol;
+class TDiagnostics;
+class TType;
+
+unsigned int CalculateVaryingLocationCount(const TType &varyingType, GLenum shaderType);
+bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics, GLenum shaderType);
+
+} // namespace sh
+
+#endif
diff --git a/gfx/angle/checkout/src/compiler/translator/VariablePacker.cpp b/gfx/angle/checkout/src/compiler/translator/VariablePacker.cpp
new file mode 100644
index 0000000000..347395d382
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/VariablePacker.cpp
@@ -0,0 +1,409 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Check whether variables fit within packing limits according to the packing rules from the GLSL ES
+// 1.00.17 spec, Appendix A, section 7.
+
+#include <algorithm>
+
+#include "angle_gl.h"
+
+#include "common/utilities.h"
+#include "compiler/translator/VariablePacker.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Expand the variable so that struct variables are split into their individual fields.
+// Will not set the mappedName or staticUse fields on the expanded variables.
+void ExpandVariable(const ShaderVariable &variable,
+ const std::string &name,
+ std::vector<ShaderVariable> *expanded);
+
+void ExpandStructVariable(const ShaderVariable &variable,
+ const std::string &name,
+ std::vector<ShaderVariable> *expanded)
+{
+ ASSERT(variable.isStruct());
+
+ const std::vector<ShaderVariable> &fields = variable.fields;
+
+ for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
+ {
+ const ShaderVariable &field = fields[fieldIndex];
+ ExpandVariable(field, name + "." + field.name, expanded);
+ }
+}
+
+void ExpandStructArrayVariable(const ShaderVariable &variable,
+ unsigned int arrayNestingIndex,
+ const std::string &name,
+ std::vector<ShaderVariable> *expanded)
+{
+ // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
+ // innermost.
+ const unsigned int currentArraySize = variable.getNestedArraySize(arrayNestingIndex);
+ for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
+ {
+ const std::string elementName = name + ArrayString(arrayElement);
+ if (arrayNestingIndex + 1u < variable.arraySizes.size())
+ {
+ ExpandStructArrayVariable(variable, arrayNestingIndex + 1u, elementName, expanded);
+ }
+ else
+ {
+ ExpandStructVariable(variable, elementName, expanded);
+ }
+ }
+}
+
+void ExpandVariable(const ShaderVariable &variable,
+ const std::string &name,
+ std::vector<ShaderVariable> *expanded)
+{
+ if (variable.isStruct())
+ {
+ if (variable.isArray())
+ {
+ ExpandStructArrayVariable(variable, 0u, name, expanded);
+ }
+ else
+ {
+ ExpandStructVariable(variable, name, expanded);
+ }
+ }
+ else
+ {
+ ShaderVariable expandedVar = variable;
+ expandedVar.name = name;
+
+ expanded->push_back(expandedVar);
+ }
+}
+
+int GetVariablePackingRows(const ShaderVariable &variable)
+{
+ return GetTypePackingRows(variable.type) * variable.getArraySizeProduct();
+}
+
+class VariablePacker
+{
+ public:
+ bool checkExpandedVariablesWithinPackingLimits(unsigned int maxVectors,
+ std::vector<sh::ShaderVariable> *variables);
+
+ private:
+ static const int kNumColumns = 4;
+ static const unsigned kColumnMask = (1 << kNumColumns) - 1;
+
+ unsigned makeColumnFlags(int column, int numComponentsPerRow);
+ void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow);
+ bool searchColumn(int column, int numRows, int *destRow, int *destSize);
+
+ int topNonFullRow_;
+ int bottomNonFullRow_;
+ int maxRows_;
+ std::vector<unsigned> rows_;
+};
+
+struct TVariableInfoComparer
+{
+ bool operator()(const sh::ShaderVariable &lhs, const sh::ShaderVariable &rhs) const
+ {
+ int lhsSortOrder = gl::VariableSortOrder(lhs.type);
+ int rhsSortOrder = gl::VariableSortOrder(rhs.type);
+ if (lhsSortOrder != rhsSortOrder)
+ {
+ return lhsSortOrder < rhsSortOrder;
+ }
+ // Sort by largest first.
+ return lhs.getArraySizeProduct() > rhs.getArraySizeProduct();
+ }
+};
+
+unsigned VariablePacker::makeColumnFlags(int column, int numComponentsPerRow)
+{
+ return ((kColumnMask << (kNumColumns - numComponentsPerRow)) & kColumnMask) >> column;
+}
+
+void VariablePacker::fillColumns(int topRow, int numRows, int column, int numComponentsPerRow)
+{
+ unsigned columnFlags = makeColumnFlags(column, numComponentsPerRow);
+ for (int r = 0; r < numRows; ++r)
+ {
+ int row = topRow + r;
+ ASSERT((rows_[row] & columnFlags) == 0);
+ rows_[row] |= columnFlags;
+ }
+}
+
+bool VariablePacker::searchColumn(int column, int numRows, int *destRow, int *destSize)
+{
+ ASSERT(destRow);
+
+ for (; topNonFullRow_ < maxRows_ && rows_[topNonFullRow_] == kColumnMask; ++topNonFullRow_)
+ {
+ }
+
+ for (; bottomNonFullRow_ >= 0 && rows_[bottomNonFullRow_] == kColumnMask; --bottomNonFullRow_)
+ {
+ }
+
+ if (bottomNonFullRow_ - topNonFullRow_ + 1 < numRows)
+ {
+ return false;
+ }
+
+ unsigned columnFlags = makeColumnFlags(column, 1);
+ int topGoodRow = 0;
+ int smallestGoodTop = -1;
+ int smallestGoodSize = maxRows_ + 1;
+ int bottomRow = bottomNonFullRow_ + 1;
+ bool found = false;
+ for (int row = topNonFullRow_; row <= bottomRow; ++row)
+ {
+ bool rowEmpty = row < bottomRow ? ((rows_[row] & columnFlags) == 0) : false;
+ if (rowEmpty)
+ {
+ if (!found)
+ {
+ topGoodRow = row;
+ found = true;
+ }
+ }
+ else
+ {
+ if (found)
+ {
+ int size = row - topGoodRow;
+ if (size >= numRows && size < smallestGoodSize)
+ {
+ smallestGoodSize = size;
+ smallestGoodTop = topGoodRow;
+ }
+ }
+ found = false;
+ }
+ }
+ if (smallestGoodTop < 0)
+ {
+ return false;
+ }
+
+ *destRow = smallestGoodTop;
+ if (destSize)
+ {
+ *destSize = smallestGoodSize;
+ }
+ return true;
+}
+
+bool VariablePacker::checkExpandedVariablesWithinPackingLimits(
+ unsigned int maxVectors,
+ std::vector<sh::ShaderVariable> *variables)
+{
+ ASSERT(maxVectors > 0);
+ maxRows_ = maxVectors;
+ topNonFullRow_ = 0;
+ bottomNonFullRow_ = maxRows_ - 1;
+
+ // Check whether each variable fits in the available vectors.
+ for (const sh::ShaderVariable &variable : *variables)
+ {
+ // Structs should have been expanded before reaching here.
+ ASSERT(!variable.isStruct());
+ if (variable.getArraySizeProduct() > maxVectors / GetTypePackingRows(variable.type))
+ {
+ return false;
+ }
+ }
+
+ // As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific
+ // order by type, then by size of array, largest first.
+ std::sort(variables->begin(), variables->end(), TVariableInfoComparer());
+ rows_.clear();
+ rows_.resize(maxVectors, 0);
+
+ // Packs the 4 column variables.
+ size_t ii = 0;
+ for (; ii < variables->size(); ++ii)
+ {
+ const sh::ShaderVariable &variable = (*variables)[ii];
+ if (GetTypePackingComponentsPerRow(variable.type) != 4)
+ {
+ break;
+ }
+ topNonFullRow_ += GetVariablePackingRows(variable);
+ if (topNonFullRow_ > maxRows_)
+ {
+ return false;
+ }
+ }
+
+ // Packs the 3 column variables.
+ int num3ColumnRows = 0;
+ for (; ii < variables->size(); ++ii)
+ {
+ const sh::ShaderVariable &variable = (*variables)[ii];
+ if (GetTypePackingComponentsPerRow(variable.type) != 3)
+ {
+ break;
+ }
+
+ num3ColumnRows += GetVariablePackingRows(variable);
+ if (topNonFullRow_ + num3ColumnRows > maxRows_)
+ {
+ return false;
+ }
+ }
+
+ fillColumns(topNonFullRow_, num3ColumnRows, 0, 3);
+
+ // Packs the 2 column variables.
+ int top2ColumnRow = topNonFullRow_ + num3ColumnRows;
+ int twoColumnRowsAvailable = maxRows_ - top2ColumnRow;
+ int rowsAvailableInColumns01 = twoColumnRowsAvailable;
+ int rowsAvailableInColumns23 = twoColumnRowsAvailable;
+ for (; ii < variables->size(); ++ii)
+ {
+ const sh::ShaderVariable &variable = (*variables)[ii];
+ if (GetTypePackingComponentsPerRow(variable.type) != 2)
+ {
+ break;
+ }
+ int numRows = GetVariablePackingRows(variable);
+ if (numRows <= rowsAvailableInColumns01)
+ {
+ rowsAvailableInColumns01 -= numRows;
+ }
+ else if (numRows <= rowsAvailableInColumns23)
+ {
+ rowsAvailableInColumns23 -= numRows;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ int numRowsUsedInColumns01 = twoColumnRowsAvailable - rowsAvailableInColumns01;
+ int numRowsUsedInColumns23 = twoColumnRowsAvailable - rowsAvailableInColumns23;
+ fillColumns(top2ColumnRow, numRowsUsedInColumns01, 0, 2);
+ fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23, 2, 2);
+
+ // Packs the 1 column variables.
+ for (; ii < variables->size(); ++ii)
+ {
+ const sh::ShaderVariable &variable = (*variables)[ii];
+ ASSERT(1 == GetTypePackingComponentsPerRow(variable.type));
+ int numRows = GetVariablePackingRows(variable);
+ int smallestColumn = -1;
+ int smallestSize = maxRows_ + 1;
+ int topRow = -1;
+ for (int column = 0; column < kNumColumns; ++column)
+ {
+ int row = 0;
+ int size = 0;
+ if (searchColumn(column, numRows, &row, &size))
+ {
+ if (size < smallestSize)
+ {
+ smallestSize = size;
+ smallestColumn = column;
+ topRow = row;
+ }
+ }
+ }
+
+ if (smallestColumn < 0)
+ {
+ return false;
+ }
+
+ fillColumns(topRow, numRows, smallestColumn, 1);
+ }
+
+ ASSERT(variables->size() == ii);
+
+ return true;
+}
+
+} // anonymous namespace
+
+int GetTypePackingComponentsPerRow(sh::GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT4x3:
+ case GL_FLOAT_VEC4:
+ case GL_INT_VEC4:
+ case GL_BOOL_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ return 4;
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_BOOL_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ return 3;
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_BOOL_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ return 2;
+ default:
+ ASSERT(gl::VariableComponentCount(type) == 1);
+ return 1;
+ }
+}
+
+int GetTypePackingRows(sh::GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x3:
+ case GL_FLOAT_MAT4x2:
+ return 4;
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT3x2:
+ return 3;
+ case GL_FLOAT_MAT2:
+ return 2;
+ default:
+ ASSERT(gl::VariableRowCount(type) == 1);
+ return 1;
+ }
+}
+
+bool CheckVariablesInPackingLimits(unsigned int maxVectors,
+ const std::vector<ShaderVariable> &variables)
+{
+ VariablePacker packer;
+ std::vector<sh::ShaderVariable> expandedVariables;
+ for (const ShaderVariable &variable : variables)
+ {
+ ExpandVariable(variable, variable.name, &expandedVariables);
+ }
+ return packer.checkExpandedVariablesWithinPackingLimits(maxVectors, &expandedVariables);
+}
+
+bool CheckVariablesInPackingLimits(unsigned int maxVectors,
+ const std::vector<ShaderVariable> &variables);
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/VariablePacker.h b/gfx/angle/checkout/src/compiler/translator/VariablePacker.h
new file mode 100644
index 0000000000..8cf621f168
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/VariablePacker.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Check whether variables fit within packing limits according to the packing rules from the GLSL ES
+// 1.00.17 spec, Appendix A, section 7.
+
+#ifndef COMPILER_TRANSLATOR_VARIABLEPACKER_H_
+#define COMPILER_TRANSLATOR_VARIABLEPACKER_H_
+
+#include <vector>
+
+#include <GLSLANG/ShaderLang.h>
+
+namespace sh
+{
+
+// Gets how many components in a row a data type takes.
+int GetTypePackingComponentsPerRow(sh::GLenum type);
+
+// Gets how many rows a data type takes.
+int GetTypePackingRows(sh::GLenum type);
+
+// Returns true if the passed in variables pack in maxVectors.
+// T should be ShaderVariable or one of the subclasses of ShaderVariable.
+bool CheckVariablesInPackingLimits(unsigned int maxVectors,
+ const std::vector<ShaderVariable> &variables);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VARIABLEPACKER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp
new file mode 100644
index 0000000000..3ff4216a0d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp
@@ -0,0 +1,156 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/VersionGLSL.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/Symbol.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr const ImmutableString kGlPointCoordString("gl_PointCoord");
+} // anonymous namespace
+
+int ShaderOutputTypeToGLSLVersion(ShShaderOutput output)
+{
+ switch (output)
+ {
+ case SH_GLSL_130_OUTPUT:
+ return GLSL_VERSION_130;
+ case SH_GLSL_140_OUTPUT:
+ return GLSL_VERSION_140;
+ case SH_GLSL_150_CORE_OUTPUT:
+ return GLSL_VERSION_150;
+ case SH_GLSL_330_CORE_OUTPUT:
+ return GLSL_VERSION_330;
+ case SH_GLSL_400_CORE_OUTPUT:
+ return GLSL_VERSION_400;
+ case SH_GLSL_410_CORE_OUTPUT:
+ return GLSL_VERSION_410;
+ case SH_GLSL_420_CORE_OUTPUT:
+ return GLSL_VERSION_420;
+ case SH_GLSL_430_CORE_OUTPUT:
+ return GLSL_VERSION_430;
+ case SH_GLSL_440_CORE_OUTPUT:
+ return GLSL_VERSION_440;
+ case SH_GLSL_450_CORE_OUTPUT:
+ return GLSL_VERSION_450;
+ case SH_GLSL_COMPATIBILITY_OUTPUT:
+ return GLSL_VERSION_110;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+// We need to scan for the following:
+// 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
+// but only at the global scope.
+// 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
+// but inside any scope.
+// 3. Call to a matrix constructor with another matrix as argument.
+// (These constructors were reserved in GLSL version 1.10.)
+// 4. Arrays as "out" function parameters.
+// GLSL spec section 6.1.1: "When calling a function, expressions that do
+// not evaluate to l-values cannot be passed to parameters declared as
+// out or inout."
+// GLSL 1.1 section 5.8: "Other binary or unary expressions,
+// non-dereferenced arrays, function names, swizzles with repeated fields,
+// and constants cannot be l-values."
+// GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
+// are built-in types, entire structures or arrays... are all l-values."
+//
+TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma, ShShaderOutput output)
+ : TIntermTraverser(true, false, false)
+{
+ mVersion = ShaderOutputTypeToGLSLVersion(output);
+ if (pragma.stdgl.invariantAll)
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+ if (type == GL_COMPUTE_SHADER)
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_430);
+ }
+}
+
+void TVersionGLSL::visitSymbol(TIntermSymbol *node)
+{
+ if (node->variable().symbolType() == SymbolType::BuiltIn &&
+ node->getName() == kGlPointCoordString)
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+}
+
+bool TVersionGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+ if (sequence.front()->getAsTyped()->getType().isInvariant())
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+ return true;
+}
+
+bool TVersionGLSL::visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *node)
+{
+ if (node->isPrecise())
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_420);
+ }
+ else
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+ return true;
+}
+
+void TVersionGLSL::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ size_t paramCount = node->getFunction()->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ const TVariable *param = node->getFunction()->getParam(i);
+ const TType &type = param->getType();
+ if (type.isArray())
+ {
+ TQualifier qualifier = type.getQualifier();
+ if ((qualifier == EvqParamOut) || (qualifier == EvqParamInOut))
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ break;
+ }
+ }
+ }
+}
+
+bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
+{
+ if (node->getOp() == EOpConstruct && node->getType().isMatrix())
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ if (sequence.size() == 1)
+ {
+ TIntermTyped *typed = sequence.front()->getAsTyped();
+ if (typed && typed->isMatrix())
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+ }
+ }
+ return true;
+}
+
+void TVersionGLSL::ensureVersionIsAtLeast(int version)
+{
+ mVersion = std::max(version, mVersion);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/VersionGLSL.h b/gfx/angle/checkout/src/compiler/translator/VersionGLSL.h
new file mode 100644
index 0000000000..706e9125e1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/VersionGLSL.h
@@ -0,0 +1,76 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_VERSIONGLSL_H_
+#define COMPILER_TRANSLATOR_VERSIONGLSL_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+#include "compiler/translator/Pragma.h"
+
+namespace sh
+{
+
+static const int GLSL_VERSION_110 = 110;
+static const int GLSL_VERSION_120 = 120;
+static const int GLSL_VERSION_130 = 130;
+static const int GLSL_VERSION_140 = 140;
+static const int GLSL_VERSION_150 = 150;
+static const int GLSL_VERSION_330 = 330;
+static const int GLSL_VERSION_400 = 400;
+static const int GLSL_VERSION_410 = 410;
+static const int GLSL_VERSION_420 = 420;
+static const int GLSL_VERSION_430 = 430;
+static const int GLSL_VERSION_440 = 440;
+static const int GLSL_VERSION_450 = 450;
+
+int ShaderOutputTypeToGLSLVersion(ShShaderOutput output);
+
+// Traverses the intermediate tree to return the minimum GLSL version
+// required to legally access all built-in features used in the shader.
+// GLSL 1.1 which is mandated by OpenGL 2.0 provides:
+// - #version and #extension to declare version and extensions.
+// - built-in functions refract, exp, and log.
+// - updated step() to compare x < edge instead of x <= edge.
+// GLSL 1.2 which is mandated by OpenGL 2.1 provides:
+// - many changes to reduce differences when compared to the ES specification.
+// - invariant keyword and its support.
+// - c++ style name hiding rules.
+// - built-in variable gl_PointCoord for fragment shaders.
+// - matrix constructors taking matrix as argument.
+// - array as "out" function parameters
+//
+// TODO: ES3 equivalent versions of GLSL
+class TVersionGLSL : public TIntermTraverser
+{
+ public:
+ TVersionGLSL(sh::GLenum type, const TPragma &pragma, ShShaderOutput output);
+
+ // If output is core profile, returns 150.
+ // If output is legacy profile,
+ // Returns 120 if the following is used the shader:
+ // - "invariant",
+ // - "gl_PointCoord",
+ // - matrix/matrix constructors
+ // - array "out" parameters
+ // Else 110 is returned.
+ int getVersion() const { return mVersion; }
+
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitAggregate(Visit, TIntermAggregate *node) override;
+ bool visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *node) override;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+
+ private:
+ void ensureVersionIsAtLeast(int version);
+
+ int mVersion;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VERSIONGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/blocklayout.cpp b/gfx/angle/checkout/src/compiler/translator/blocklayout.cpp
new file mode 100644
index 0000000000..24a2640dca
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/blocklayout.cpp
@@ -0,0 +1,666 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// blocklayout.cpp:
+// Implementation for block layout classes and methods.
+//
+
+#include "compiler/translator/blocklayout.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+namespace
+{
+class BlockLayoutMapVisitor : public BlockEncoderVisitor
+{
+ public:
+ BlockLayoutMapVisitor(BlockLayoutMap *blockInfoOut,
+ const std::string &instanceName,
+ BlockLayoutEncoder *encoder)
+ : BlockEncoderVisitor(instanceName, instanceName, encoder), mInfoOut(blockInfoOut)
+ {}
+
+ void encodeVariable(const ShaderVariable &variable,
+ const BlockMemberInfo &variableInfo,
+ const std::string &name,
+ const std::string &mappedName) override
+ {
+ ASSERT(!gl::IsSamplerType(variable.type));
+ if (!gl::IsOpaqueType(variable.type))
+ {
+ (*mInfoOut)[name] = variableInfo;
+ }
+ }
+
+ private:
+ BlockLayoutMap *mInfoOut;
+};
+
+template <typename VarT>
+void GetInterfaceBlockInfo(const std::vector<VarT> &fields,
+ const std::string &prefix,
+ BlockLayoutEncoder *encoder,
+ bool inRowMajorLayout,
+ bool onlyActiveVariables,
+ BlockLayoutMap *blockInfoOut)
+{
+ BlockLayoutMapVisitor visitor(blockInfoOut, prefix, encoder);
+ if (onlyActiveVariables)
+ {
+ TraverseActiveShaderVariables(fields, inRowMajorLayout, &visitor);
+ }
+ else
+ {
+ TraverseShaderVariables(fields, inRowMajorLayout, &visitor);
+ }
+}
+
+void TraverseStructVariable(const ShaderVariable &variable,
+ bool isRowMajorLayout,
+ ShaderVariableVisitor *visitor)
+{
+ const std::vector<ShaderVariable> &fields = variable.fields;
+
+ visitor->enterStructAccess(variable, isRowMajorLayout);
+ TraverseShaderVariables(fields, isRowMajorLayout, visitor);
+ visitor->exitStructAccess(variable, isRowMajorLayout);
+}
+
+void TraverseStructArrayVariable(const ShaderVariable &variable,
+ bool inRowMajorLayout,
+ ShaderVariableVisitor *visitor)
+{
+ visitor->enterArray(variable);
+
+ // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
+ // innermost. We make a special case for unsized arrays.
+ const unsigned int currentArraySize = variable.getNestedArraySize(0);
+ for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
+ {
+ visitor->enterArrayElement(variable, arrayElement);
+ ShaderVariable elementVar = variable;
+ elementVar.indexIntoArray(arrayElement);
+
+ if (variable.arraySizes.size() > 1u)
+ {
+ TraverseStructArrayVariable(elementVar, inRowMajorLayout, visitor);
+ }
+ else
+ {
+ TraverseStructVariable(elementVar, inRowMajorLayout, visitor);
+ }
+
+ visitor->exitArrayElement(variable, arrayElement);
+ }
+
+ visitor->exitArray(variable);
+}
+
+void TraverseArrayOfArraysVariable(const ShaderVariable &variable,
+ unsigned int arrayNestingIndex,
+ bool isRowMajorMatrix,
+ ShaderVariableVisitor *visitor)
+{
+ visitor->enterArray(variable);
+
+ const unsigned int currentArraySize = variable.getNestedArraySize(arrayNestingIndex);
+ unsigned int count = std::max(currentArraySize, 1u);
+ for (unsigned int arrayElement = 0u; arrayElement < count; ++arrayElement)
+ {
+ visitor->enterArrayElement(variable, arrayElement);
+
+ ShaderVariable elementVar = variable;
+ elementVar.indexIntoArray(arrayElement);
+
+ if (arrayNestingIndex + 2u < variable.arraySizes.size())
+ {
+ TraverseArrayOfArraysVariable(elementVar, arrayNestingIndex, isRowMajorMatrix, visitor);
+ }
+ else
+ {
+ if (gl::IsSamplerType(variable.type) || gl::IsImageType(variable.type) ||
+ variable.isFragmentInOut)
+ {
+ visitor->visitOpaqueObject(elementVar);
+ }
+ else
+ {
+ visitor->visitVariable(elementVar, isRowMajorMatrix);
+ }
+ }
+
+ visitor->exitArrayElement(variable, arrayElement);
+ }
+
+ visitor->exitArray(variable);
+}
+
+std::string CollapseNameStack(const std::vector<std::string> &nameStack)
+{
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
+ for (const std::string &part : nameStack)
+ {
+ strstr << part;
+ }
+ return strstr.str();
+}
+
+size_t GetStd430BaseAlignment(GLenum variableType, bool isRowMajor)
+{
+ GLenum flippedType = isRowMajor ? variableType : gl::TransposeMatrixType(variableType);
+ size_t numComponents = static_cast<size_t>(gl::VariableColumnCount(flippedType));
+ return ComponentAlignment(numComponents);
+}
+
+class BaseAlignmentVisitor : public ShaderVariableVisitor
+{
+ public:
+ BaseAlignmentVisitor() = default;
+ void visitVariable(const ShaderVariable &variable, bool isRowMajor) override
+ {
+ size_t baseAlignment = GetStd430BaseAlignment(variable.type, isRowMajor);
+ mCurrentAlignment = std::max(mCurrentAlignment, baseAlignment);
+ }
+
+ // This is in components rather than bytes.
+ size_t getBaseAlignment() const { return mCurrentAlignment; }
+
+ private:
+ size_t mCurrentAlignment = 0;
+};
+} // anonymous namespace
+
+// BlockLayoutEncoder implementation.
+BlockLayoutEncoder::BlockLayoutEncoder() : mCurrentOffset(0) {}
+
+BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix)
+{
+ int arrayStride;
+ int matrixStride;
+
+ getBlockLayoutInfo(type, arraySizes, isRowMajorMatrix, &arrayStride, &matrixStride);
+
+ const BlockMemberInfo memberInfo(static_cast<int>(mCurrentOffset * kBytesPerComponent),
+ static_cast<int>(arrayStride * kBytesPerComponent),
+ static_cast<int>(matrixStride * kBytesPerComponent),
+ isRowMajorMatrix);
+
+ advanceOffset(type, arraySizes, isRowMajorMatrix, arrayStride, matrixStride);
+
+ return memberInfo;
+}
+
+BlockMemberInfo BlockLayoutEncoder::encodeArrayOfPreEncodedStructs(
+ size_t size,
+ const std::vector<unsigned int> &arraySizes)
+{
+ const unsigned int innerArraySizeProduct = gl::InnerArraySizeProduct(arraySizes);
+ const unsigned int outermostArraySize = gl::OutermostArraySize(arraySizes);
+
+ // The size of struct is expected to be already aligned appropriately.
+ const size_t arrayStride = size * innerArraySizeProduct;
+
+ const BlockMemberInfo memberInfo(static_cast<int>(mCurrentOffset * kBytesPerComponent),
+ static_cast<int>(arrayStride), -1, false);
+
+ angle::base::CheckedNumeric<size_t> checkedOffset(arrayStride);
+ checkedOffset *= outermostArraySize;
+ checkedOffset /= kBytesPerComponent;
+ checkedOffset += mCurrentOffset;
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+
+ return memberInfo;
+}
+
+size_t BlockLayoutEncoder::getCurrentOffset() const
+{
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset *= kBytesPerComponent;
+ return checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+}
+
+size_t BlockLayoutEncoder::getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor)
+{
+ size_t currentOffset = mCurrentOffset;
+ mCurrentOffset = 0;
+ BlockEncoderVisitor visitor("", "", this);
+ enterAggregateType(structVar);
+ TraverseShaderVariables(structVar.fields, isRowMajor, &visitor);
+ exitAggregateType(structVar);
+ size_t structVarSize = getCurrentOffset();
+ mCurrentOffset = currentOffset;
+ return structVarSize;
+}
+
+// static
+size_t BlockLayoutEncoder::GetBlockRegister(const BlockMemberInfo &info)
+{
+ return (info.offset / kBytesPerComponent) / kComponentsPerRegister;
+}
+
+// static
+size_t BlockLayoutEncoder::GetBlockRegisterElement(const BlockMemberInfo &info)
+{
+ return (info.offset / kBytesPerComponent) % kComponentsPerRegister;
+}
+
+void BlockLayoutEncoder::align(size_t baseAlignment)
+{
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset += baseAlignment;
+ checkedOffset -= 1;
+ angle::base::CheckedNumeric<size_t> checkedAlignmentOffset = checkedOffset;
+ checkedAlignmentOffset %= baseAlignment;
+ checkedOffset -= checkedAlignmentOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+}
+
+// StubBlockEncoder implementation.
+void StubBlockEncoder::getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut)
+{
+ *arrayStrideOut = 0;
+ *matrixStrideOut = 0;
+}
+
+// Std140BlockEncoder implementation.
+Std140BlockEncoder::Std140BlockEncoder() {}
+
+void Std140BlockEncoder::enterAggregateType(const ShaderVariable &structVar)
+{
+ align(getBaseAlignment(structVar));
+}
+
+void Std140BlockEncoder::exitAggregateType(const ShaderVariable &structVar)
+{
+ align(getBaseAlignment(structVar));
+}
+
+void Std140BlockEncoder::getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut)
+{
+ // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
+ ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == kBytesPerComponent);
+
+ size_t baseAlignment = 0;
+ int matrixStride = 0;
+ int arrayStride = 0;
+
+ if (gl::IsMatrixType(type))
+ {
+ baseAlignment = getTypeBaseAlignment(type, isRowMajorMatrix);
+ matrixStride = static_cast<int>(getTypeBaseAlignment(type, isRowMajorMatrix));
+
+ if (!arraySizes.empty())
+ {
+ const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ arrayStride =
+ static_cast<int>(getTypeBaseAlignment(type, isRowMajorMatrix) * numRegisters);
+ }
+ }
+ else if (!arraySizes.empty())
+ {
+ baseAlignment = static_cast<int>(getTypeBaseAlignment(type, false));
+ arrayStride = static_cast<int>(getTypeBaseAlignment(type, false));
+ }
+ else
+ {
+ const size_t numComponents = static_cast<size_t>(gl::VariableComponentCount(type));
+ baseAlignment = ComponentAlignment(numComponents);
+ }
+
+ align(baseAlignment);
+
+ *matrixStrideOut = matrixStride;
+ *arrayStrideOut = arrayStride;
+}
+
+void Std140BlockEncoder::advanceOffset(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride)
+{
+ if (!arraySizes.empty())
+ {
+ angle::base::CheckedNumeric<size_t> checkedOffset(arrayStride);
+ checkedOffset *= gl::ArraySizeProduct(arraySizes);
+ checkedOffset += mCurrentOffset;
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+ }
+ else if (gl::IsMatrixType(type))
+ {
+ angle::base::CheckedNumeric<size_t> checkedOffset(matrixStride);
+ checkedOffset *= gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ checkedOffset += mCurrentOffset;
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+ }
+ else
+ {
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset += gl::VariableComponentCount(type);
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+ }
+}
+
+size_t Std140BlockEncoder::getBaseAlignment(const ShaderVariable &variable) const
+{
+ return kComponentsPerRegister;
+}
+
+size_t Std140BlockEncoder::getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const
+{
+ return kComponentsPerRegister;
+}
+
+// Std430BlockEncoder implementation.
+Std430BlockEncoder::Std430BlockEncoder() {}
+
+size_t Std430BlockEncoder::getBaseAlignment(const ShaderVariable &shaderVar) const
+{
+ if (shaderVar.isStruct())
+ {
+ BaseAlignmentVisitor visitor;
+ TraverseShaderVariables(shaderVar.fields, false, &visitor);
+ return visitor.getBaseAlignment();
+ }
+
+ return GetStd430BaseAlignment(shaderVar.type, shaderVar.isRowMajorLayout);
+}
+
+size_t Std430BlockEncoder::getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const
+{
+ return GetStd430BaseAlignment(type, isRowMajorMatrix);
+}
+
+void GetInterfaceBlockInfo(const std::vector<ShaderVariable> &fields,
+ const std::string &prefix,
+ BlockLayoutEncoder *encoder,
+ BlockLayoutMap *blockInfoOut)
+{
+ // Matrix packing is always recorded in individual fields, so they'll set the row major layout
+ // flag to true if needed.
+ // Iterates over all variables.
+ GetInterfaceBlockInfo(fields, prefix, encoder, false, false, blockInfoOut);
+}
+
+void GetActiveUniformBlockInfo(const std::vector<ShaderVariable> &uniforms,
+ const std::string &prefix,
+ BlockLayoutEncoder *encoder,
+ BlockLayoutMap *blockInfoOut)
+{
+ // Matrix packing is always recorded in individual fields, so they'll set the row major layout
+ // flag to true if needed.
+ // Iterates only over the active variables.
+ GetInterfaceBlockInfo(uniforms, prefix, encoder, false, true, blockInfoOut);
+}
+
+// VariableNameVisitor implementation.
+VariableNameVisitor::VariableNameVisitor(const std::string &namePrefix,
+ const std::string &mappedNamePrefix)
+{
+ if (!namePrefix.empty())
+ {
+ mNameStack.push_back(namePrefix + ".");
+ }
+
+ if (!mappedNamePrefix.empty())
+ {
+ mMappedNameStack.push_back(mappedNamePrefix + ".");
+ }
+}
+
+VariableNameVisitor::~VariableNameVisitor() = default;
+
+void VariableNameVisitor::enterStruct(const ShaderVariable &structVar)
+{
+ mNameStack.push_back(structVar.name);
+ mMappedNameStack.push_back(structVar.mappedName);
+}
+
+void VariableNameVisitor::exitStruct(const ShaderVariable &structVar)
+{
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+}
+
+void VariableNameVisitor::enterStructAccess(const ShaderVariable &structVar, bool isRowMajor)
+{
+ mNameStack.push_back(".");
+ mMappedNameStack.push_back(".");
+}
+
+void VariableNameVisitor::exitStructAccess(const ShaderVariable &structVar, bool isRowMajor)
+{
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+}
+
+void VariableNameVisitor::enterArray(const ShaderVariable &arrayVar)
+{
+ if (!arrayVar.hasParentArrayIndex() && !arrayVar.isStruct())
+ {
+ mNameStack.push_back(arrayVar.name);
+ mMappedNameStack.push_back(arrayVar.mappedName);
+ }
+ mArraySizeStack.push_back(arrayVar.getOutermostArraySize());
+}
+
+void VariableNameVisitor::exitArray(const ShaderVariable &arrayVar)
+{
+ if (!arrayVar.hasParentArrayIndex() && !arrayVar.isStruct())
+ {
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+ }
+ mArraySizeStack.pop_back();
+}
+
+void VariableNameVisitor::enterArrayElement(const ShaderVariable &arrayVar,
+ unsigned int arrayElement)
+{
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
+ strstr << "[" << arrayElement << "]";
+ std::string elementString = strstr.str();
+ mNameStack.push_back(elementString);
+ mMappedNameStack.push_back(elementString);
+}
+
+void VariableNameVisitor::exitArrayElement(const ShaderVariable &arrayVar,
+ unsigned int arrayElement)
+{
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+}
+
+std::string VariableNameVisitor::collapseNameStack() const
+{
+ return CollapseNameStack(mNameStack);
+}
+
+std::string VariableNameVisitor::collapseMappedNameStack() const
+{
+ return CollapseNameStack(mMappedNameStack);
+}
+
+void VariableNameVisitor::visitOpaqueObject(const sh::ShaderVariable &variable)
+{
+ if (!variable.hasParentArrayIndex())
+ {
+ mNameStack.push_back(variable.name);
+ mMappedNameStack.push_back(variable.mappedName);
+ }
+
+ std::string name = collapseNameStack();
+ std::string mappedName = collapseMappedNameStack();
+
+ if (!variable.hasParentArrayIndex())
+ {
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+ }
+
+ visitNamedOpaqueObject(variable, name, mappedName, mArraySizeStack);
+}
+
+void VariableNameVisitor::visitVariable(const ShaderVariable &variable, bool isRowMajor)
+{
+ if (!variable.hasParentArrayIndex())
+ {
+ mNameStack.push_back(variable.name);
+ mMappedNameStack.push_back(variable.mappedName);
+ }
+
+ std::string name = collapseNameStack();
+ std::string mappedName = collapseMappedNameStack();
+
+ if (!variable.hasParentArrayIndex())
+ {
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+ }
+
+ visitNamedVariable(variable, isRowMajor, name, mappedName, mArraySizeStack);
+}
+
+// BlockEncoderVisitor implementation.
+BlockEncoderVisitor::BlockEncoderVisitor(const std::string &namePrefix,
+ const std::string &mappedNamePrefix,
+ BlockLayoutEncoder *encoder)
+ : VariableNameVisitor(namePrefix, mappedNamePrefix), mEncoder(encoder)
+{}
+
+BlockEncoderVisitor::~BlockEncoderVisitor() = default;
+
+void BlockEncoderVisitor::enterStructAccess(const ShaderVariable &structVar, bool isRowMajor)
+{
+ mStructStackSize++;
+ if (!mIsTopLevelArrayStrideReady)
+ {
+ size_t structSize = mEncoder->getShaderVariableSize(structVar, isRowMajor);
+ mTopLevelArrayStride *= structSize;
+ mIsTopLevelArrayStrideReady = true;
+ }
+
+ VariableNameVisitor::enterStructAccess(structVar, isRowMajor);
+ mEncoder->enterAggregateType(structVar);
+}
+
+void BlockEncoderVisitor::exitStructAccess(const ShaderVariable &structVar, bool isRowMajor)
+{
+ mStructStackSize--;
+ mEncoder->exitAggregateType(structVar);
+ VariableNameVisitor::exitStructAccess(structVar, isRowMajor);
+}
+
+void BlockEncoderVisitor::enterArrayElement(const sh::ShaderVariable &arrayVar,
+ unsigned int arrayElement)
+{
+ if (mStructStackSize == 0 && !arrayVar.hasParentArrayIndex())
+ {
+ // From the ES 3.1 spec "7.3.1.1 Naming Active Resources":
+ // For an active shader storage block member declared as an array of an aggregate type,
+ // an entry will be generated only for the first array element, regardless of its type.
+ // Such block members are referred to as top-level arrays. If the block member is an
+ // aggregate type, the enumeration rules are then applied recursively.
+ if (arrayElement == 0)
+ {
+ mTopLevelArraySize = arrayVar.getOutermostArraySize();
+ mTopLevelArrayStride = arrayVar.getInnerArraySizeProduct();
+ mIsTopLevelArrayStrideReady = false;
+ }
+ else
+ {
+ mSkipEnabled = true;
+ }
+ }
+ VariableNameVisitor::enterArrayElement(arrayVar, arrayElement);
+}
+
+void BlockEncoderVisitor::exitArrayElement(const sh::ShaderVariable &arrayVar,
+ unsigned int arrayElement)
+{
+ if (mStructStackSize == 0 && !arrayVar.hasParentArrayIndex())
+ {
+ mTopLevelArraySize = 1;
+ mTopLevelArrayStride = 0;
+ mIsTopLevelArrayStrideReady = true;
+ mSkipEnabled = false;
+ }
+ VariableNameVisitor::exitArrayElement(arrayVar, arrayElement);
+}
+
+void BlockEncoderVisitor::visitNamedVariable(const ShaderVariable &variable,
+ bool isRowMajor,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes)
+{
+ std::vector<unsigned int> innermostArraySize;
+
+ if (variable.isArray())
+ {
+ innermostArraySize.push_back(variable.getNestedArraySize(0));
+ }
+ BlockMemberInfo variableInfo =
+ mEncoder->encodeType(variable.type, innermostArraySize, isRowMajor);
+ if (!mIsTopLevelArrayStrideReady)
+ {
+ ASSERT(mTopLevelArrayStride);
+ mTopLevelArrayStride *= variableInfo.arrayStride;
+ mIsTopLevelArrayStrideReady = true;
+ }
+ variableInfo.topLevelArrayStride = mTopLevelArrayStride;
+ encodeVariable(variable, variableInfo, name, mappedName);
+}
+
+void TraverseShaderVariable(const ShaderVariable &variable,
+ bool isRowMajorLayout,
+ ShaderVariableVisitor *visitor)
+{
+ bool rowMajorLayout = (isRowMajorLayout || variable.isRowMajorLayout);
+ bool isRowMajor = rowMajorLayout && gl::IsMatrixType(variable.type);
+
+ if (variable.isStruct())
+ {
+ visitor->enterStruct(variable);
+ if (variable.isArray())
+ {
+ TraverseStructArrayVariable(variable, rowMajorLayout, visitor);
+ }
+ else
+ {
+ TraverseStructVariable(variable, rowMajorLayout, visitor);
+ }
+ visitor->exitStruct(variable);
+ }
+ else if (variable.isArrayOfArrays())
+ {
+ TraverseArrayOfArraysVariable(variable, 0u, isRowMajor, visitor);
+ }
+ else if (gl::IsSamplerType(variable.type) || gl::IsImageType(variable.type) ||
+ variable.isFragmentInOut)
+ {
+ visitor->visitOpaqueObject(variable);
+ }
+ else
+ {
+ visitor->visitVariable(variable, isRowMajor);
+ }
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/blocklayout.h b/gfx/angle/checkout/src/compiler/translator/blocklayout.h
new file mode 100644
index 0000000000..97f9daa251
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/blocklayout.h
@@ -0,0 +1,322 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// blocklayout.h:
+// Methods and classes related to uniform layout and packing in GLSL and HLSL.
+//
+
+#ifndef COMMON_BLOCKLAYOUT_H_
+#define COMMON_BLOCKLAYOUT_H_
+
+#include <cstddef>
+#include <map>
+#include <vector>
+
+#include <GLSLANG/ShaderLang.h>
+#include "angle_gl.h"
+
+namespace sh
+{
+struct ShaderVariable;
+struct InterfaceBlock;
+
+struct BlockMemberInfo
+{
+ constexpr BlockMemberInfo() = default;
+
+ constexpr BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
+ : offset(offset),
+ arrayStride(arrayStride),
+ matrixStride(matrixStride),
+ isRowMajorMatrix(isRowMajorMatrix)
+ {}
+
+ constexpr BlockMemberInfo(int offset,
+ int arrayStride,
+ int matrixStride,
+ bool isRowMajorMatrix,
+ int topLevelArrayStride)
+ : offset(offset),
+ arrayStride(arrayStride),
+ matrixStride(matrixStride),
+ isRowMajorMatrix(isRowMajorMatrix),
+ topLevelArrayStride(topLevelArrayStride)
+ {}
+
+ // A single integer identifying the offset of an active variable.
+ int offset = -1;
+
+ // A single integer identifying the stride between array elements in an active variable.
+ int arrayStride = -1;
+
+ // A single integer identifying the stride between columns of a column-major matrix or rows of a
+ // row-major matrix.
+ int matrixStride = -1;
+
+ // A single integer identifying whether an active variable is a row-major matrix.
+ bool isRowMajorMatrix = false;
+
+ // A single integer identifying the number of active array elements of the top-level shader
+ // storage block member containing the active variable.
+ int topLevelArrayStride = -1;
+};
+
+constexpr size_t ComponentAlignment(size_t numComponents)
+{
+ return (numComponents == 3u ? 4u : numComponents);
+}
+
+constexpr BlockMemberInfo kDefaultBlockMemberInfo;
+
+class BlockLayoutEncoder
+{
+ public:
+ BlockLayoutEncoder();
+ virtual ~BlockLayoutEncoder() {}
+
+ BlockMemberInfo encodeType(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix);
+ // Advance the offset based on struct size and array dimensions. Size can be calculated with
+ // getShaderVariableSize() or equivalent. |enterAggregateType|/|exitAggregateType| is necessary
+ // around this call.
+ BlockMemberInfo encodeArrayOfPreEncodedStructs(size_t size,
+ const std::vector<unsigned int> &arraySizes);
+
+ size_t getCurrentOffset() const;
+ size_t getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor);
+
+ // Called when entering/exiting a structure variable.
+ virtual void enterAggregateType(const ShaderVariable &structVar) = 0;
+ virtual void exitAggregateType(const ShaderVariable &structVar) = 0;
+
+ static constexpr size_t kBytesPerComponent = 4u;
+ static constexpr unsigned int kComponentsPerRegister = 4u;
+
+ static size_t GetBlockRegister(const BlockMemberInfo &info);
+ static size_t GetBlockRegisterElement(const BlockMemberInfo &info);
+
+ protected:
+ void align(size_t baseAlignment);
+
+ virtual void getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut) = 0;
+ virtual void advanceOffset(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride) = 0;
+
+ size_t mCurrentOffset;
+};
+
+// Will return default values for everything.
+class StubBlockEncoder : public BlockLayoutEncoder
+{
+ public:
+ StubBlockEncoder() = default;
+
+ void enterAggregateType(const ShaderVariable &structVar) override {}
+ void exitAggregateType(const ShaderVariable &structVar) override {}
+
+ protected:
+ void getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut) override;
+
+ void advanceOffset(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride) override
+ {}
+};
+
+// Block layout according to the std140 block layout
+// See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
+
+class Std140BlockEncoder : public BlockLayoutEncoder
+{
+ public:
+ Std140BlockEncoder();
+
+ void enterAggregateType(const ShaderVariable &structVar) override;
+ void exitAggregateType(const ShaderVariable &structVar) override;
+
+ protected:
+ void getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut) override;
+ void advanceOffset(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride) override;
+
+ virtual size_t getBaseAlignment(const ShaderVariable &variable) const;
+ virtual size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const;
+};
+
+class Std430BlockEncoder : public Std140BlockEncoder
+{
+ public:
+ Std430BlockEncoder();
+
+ protected:
+ size_t getBaseAlignment(const ShaderVariable &variable) const override;
+ size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const override;
+};
+
+using BlockLayoutMap = std::map<std::string, BlockMemberInfo>;
+
+void GetInterfaceBlockInfo(const std::vector<ShaderVariable> &fields,
+ const std::string &prefix,
+ BlockLayoutEncoder *encoder,
+ BlockLayoutMap *blockInfoOut);
+
+// Used for laying out the default uniform block on the Vulkan backend.
+void GetActiveUniformBlockInfo(const std::vector<ShaderVariable> &uniforms,
+ const std::string &prefix,
+ BlockLayoutEncoder *encoder,
+ BlockLayoutMap *blockInfoOut);
+
+class ShaderVariableVisitor
+{
+ public:
+ virtual ~ShaderVariableVisitor() {}
+
+ virtual void enterStruct(const ShaderVariable &structVar) {}
+ virtual void exitStruct(const ShaderVariable &structVar) {}
+
+ virtual void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
+ virtual void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
+
+ virtual void enterArray(const ShaderVariable &arrayVar) {}
+ virtual void exitArray(const ShaderVariable &arrayVar) {}
+
+ virtual void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}
+ virtual void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}
+
+ virtual void visitOpaqueObject(const sh::ShaderVariable &variable) {}
+
+ virtual void visitVariable(const ShaderVariable &variable, bool isRowMajor) = 0;
+
+ protected:
+ ShaderVariableVisitor() {}
+};
+
+class VariableNameVisitor : public ShaderVariableVisitor
+{
+ public:
+ VariableNameVisitor(const std::string &namePrefix, const std::string &mappedNamePrefix);
+ ~VariableNameVisitor() override;
+
+ void enterStruct(const ShaderVariable &structVar) override;
+ void exitStruct(const ShaderVariable &structVar) override;
+ void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
+ void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
+ void enterArray(const ShaderVariable &arrayVar) override;
+ void exitArray(const ShaderVariable &arrayVar) override;
+ void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
+ void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
+
+ protected:
+ virtual void visitNamedOpaqueObject(const sh::ShaderVariable &variable,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes)
+ {}
+ virtual void visitNamedVariable(const ShaderVariable &variable,
+ bool isRowMajor,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes) = 0;
+
+ std::string collapseNameStack() const;
+ std::string collapseMappedNameStack() const;
+
+ private:
+ void visitOpaqueObject(const sh::ShaderVariable &variable) final;
+ void visitVariable(const ShaderVariable &variable, bool isRowMajor) final;
+
+ std::vector<std::string> mNameStack;
+ std::vector<std::string> mMappedNameStack;
+ std::vector<unsigned int> mArraySizeStack;
+};
+
+class BlockEncoderVisitor : public VariableNameVisitor
+{
+ public:
+ BlockEncoderVisitor(const std::string &namePrefix,
+ const std::string &mappedNamePrefix,
+ BlockLayoutEncoder *encoder);
+ ~BlockEncoderVisitor() override;
+
+ void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
+ void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
+ void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
+ void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
+
+ void visitNamedVariable(const ShaderVariable &variable,
+ bool isRowMajor,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes) override;
+
+ virtual void encodeVariable(const ShaderVariable &variable,
+ const BlockMemberInfo &variableInfo,
+ const std::string &name,
+ const std::string &mappedName)
+ {}
+
+ protected:
+ int mTopLevelArraySize = 1;
+ int mTopLevelArrayStride = 0;
+ bool mIsTopLevelArrayStrideReady = true;
+ bool mSkipEnabled = false;
+
+ private:
+ BlockLayoutEncoder *mEncoder;
+ unsigned int mStructStackSize = 0;
+};
+
+void TraverseShaderVariable(const ShaderVariable &variable,
+ bool isRowMajorLayout,
+ ShaderVariableVisitor *visitor);
+
+template <typename T>
+void TraverseShaderVariables(const std::vector<T> &vars,
+ bool isRowMajorLayout,
+ ShaderVariableVisitor *visitor)
+{
+ for (const T &var : vars)
+ {
+ TraverseShaderVariable(var, isRowMajorLayout, visitor);
+ }
+}
+
+template <typename T>
+void TraverseActiveShaderVariables(const std::vector<T> &vars,
+ bool isRowMajorLayout,
+ ShaderVariableVisitor *visitor)
+{
+ for (const T &var : vars)
+ {
+ if (var.active)
+ {
+ TraverseShaderVariable(var, isRowMajorLayout, visitor);
+ }
+ }
+}
+} // namespace sh
+
+#endif // COMMON_BLOCKLAYOUT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp
new file mode 100644
index 0000000000..9030c7f370
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp
@@ -0,0 +1,167 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// blocklayout.cpp:
+// Implementation for block layout classes and methods.
+//
+
+#include "compiler/translator/blocklayoutHLSL.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+
+namespace sh
+{
+
+HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices)
+ : mEncoderStrategy(strategy), mTransposeMatrices(transposeMatrices)
+{}
+
+void HLSLBlockEncoder::enterAggregateType(const ShaderVariable &structVar)
+{
+ align(kComponentsPerRegister);
+}
+
+void HLSLBlockEncoder::exitAggregateType(const ShaderVariable &structVar) {}
+
+void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut)
+{
+ GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
+
+ // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
+ ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == kBytesPerComponent);
+
+ int matrixStride = 0;
+ int arrayStride = 0;
+
+ // if variables are not to be packed, or we're about to
+ // pack a matrix or array, skip to the start of the next
+ // register
+ if (!isPacked() || gl::IsMatrixType(type) || !arraySizes.empty())
+ {
+ align(kComponentsPerRegister);
+ }
+
+ if (gl::IsMatrixType(type))
+ {
+ matrixStride = kComponentsPerRegister;
+
+ if (!arraySizes.empty())
+ {
+ const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ arrayStride = kComponentsPerRegister * numRegisters;
+ }
+ }
+ else if (!arraySizes.empty())
+ {
+ arrayStride = kComponentsPerRegister;
+ }
+ else if (isPacked())
+ {
+ int numComponents = gl::VariableComponentCount(type);
+ if ((numComponents + (mCurrentOffset % kComponentsPerRegister)) > kComponentsPerRegister)
+ {
+ align(kComponentsPerRegister);
+ }
+ }
+
+ *matrixStrideOut = matrixStride;
+ *arrayStrideOut = arrayStride;
+}
+
+void HLSLBlockEncoder::advanceOffset(GLenum typeIn,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride)
+{
+ GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
+
+ if (!arraySizes.empty())
+ {
+ unsigned int arraySize = gl::ArraySizeProduct(arraySizes);
+ if (arraySize > 0)
+ {
+ mCurrentOffset += arrayStride * (arraySize - 1);
+ }
+ }
+
+ if (gl::IsMatrixType(type))
+ {
+ ASSERT(matrixStride == kComponentsPerRegister);
+ const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ const int numComponents = gl::MatrixComponentCount(type, isRowMajorMatrix);
+ mCurrentOffset += kComponentsPerRegister * (numRegisters - 1);
+ mCurrentOffset += numComponents;
+ }
+ else if (isPacked())
+ {
+ mCurrentOffset += gl::VariableComponentCount(type);
+ }
+ else
+ {
+ mCurrentOffset += kComponentsPerRegister;
+ }
+}
+
+void HLSLBlockEncoder::skipRegisters(unsigned int numRegisters)
+{
+ mCurrentOffset += (numRegisters * kComponentsPerRegister);
+}
+
+HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor(
+ ShShaderOutput outputType)
+{
+ switch (outputType)
+ {
+ case SH_HLSL_3_0_OUTPUT:
+ return ENCODE_LOOSE;
+ case SH_HLSL_4_1_OUTPUT:
+ case SH_HLSL_4_0_FL9_3_OUTPUT:
+ return ENCODE_PACKED;
+ default:
+ UNREACHABLE();
+ return ENCODE_PACKED;
+ }
+}
+
+template <class ShaderVarType>
+void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *encoder)
+{
+ if (variable.isStruct())
+ {
+ for (size_t arrayElement = 0; arrayElement < variable.getArraySizeProduct(); arrayElement++)
+ {
+ encoder->enterAggregateType(variable);
+
+ for (const ShaderVariable &field : variable.fields)
+ {
+ HLSLVariableRegisterCount(field, encoder);
+ }
+
+ encoder->exitAggregateType(variable);
+ }
+ }
+ else
+ {
+ // We operate only on varyings and uniforms, which do not have matrix layout qualifiers
+ encoder->encodeType(variable.type, variable.arraySizes, false);
+ }
+}
+
+unsigned int HLSLVariableRegisterCount(const ShaderVariable &variable, ShShaderOutput outputType)
+{
+ HLSLBlockEncoder encoder(HLSLBlockEncoder::GetStrategyFor(outputType), true);
+ HLSLVariableRegisterCount(variable, &encoder);
+
+ const size_t registerBytes = (encoder.kBytesPerComponent * encoder.kComponentsPerRegister);
+ return static_cast<unsigned int>(
+ rx::roundUp<size_t>(encoder.getCurrentOffset(), registerBytes) / registerBytes);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.h b/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.h
new file mode 100644
index 0000000000..8ed46b7728
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.h
@@ -0,0 +1,68 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// blocklayout.h:
+// Methods and classes related to uniform layout and packing in GLSL and HLSL.
+//
+
+#ifndef COMMON_BLOCKLAYOUTHLSL_H_
+#define COMMON_BLOCKLAYOUTHLSL_H_
+
+#include <cstddef>
+#include <vector>
+
+#include <GLSLANG/ShaderLang.h>
+#include "angle_gl.h"
+#include "blocklayout.h"
+
+namespace sh
+{
+// Block layout packed according to the D3D9 or default D3D10+ register packing rules
+// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
+// The strategy should be ENCODE_LOOSE for D3D9 constant blocks, and ENCODE_PACKED
+// for everything else (D3D10+ constant blocks and all attributes/varyings).
+
+class HLSLBlockEncoder : public BlockLayoutEncoder
+{
+ public:
+ enum HLSLBlockEncoderStrategy
+ {
+ ENCODE_PACKED,
+ ENCODE_LOOSE
+ };
+
+ HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices);
+
+ void enterAggregateType(const ShaderVariable &structVar) override;
+ void exitAggregateType(const ShaderVariable &structVar) override;
+ void skipRegisters(unsigned int numRegisters);
+
+ bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
+
+ static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
+
+ protected:
+ void getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut) override;
+ void advanceOffset(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride) override;
+
+ HLSLBlockEncoderStrategy mEncoderStrategy;
+ bool mTransposeMatrices;
+};
+
+// This method returns the number of used registers for a ShaderVariable. It is dependent on the
+// HLSLBlockEncoder class to count the number of used registers in a struct (which are individually
+// packed according to the same rules).
+unsigned int HLSLVariableRegisterCount(const ShaderVariable &variable, ShShaderOutput outputType);
+} // namespace sh
+
+#endif // COMMON_BLOCKLAYOUTHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp b/gfx/angle/checkout/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp
new file mode 100644
index 0000000000..5b81f13869
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp
@@ -0,0 +1,881 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_emulated_builtin_function_tables.py using data from
+// emulated_builtin_function_data_hlsl.json.
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// emulated_builtin_functions_hlsl:
+// HLSL code for emulating GLSL builtin functions not present in HLSL.
+
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+
+namespace sh
+{
+
+namespace
+{
+
+struct FunctionPair
+{
+ constexpr FunctionPair(const TSymbolUniqueId &idIn, const char *bodyIn)
+ : id(idIn.get()), body(bodyIn)
+ {}
+
+ int id;
+ const char *body;
+};
+
+constexpr FunctionPair g_hlslFunctions[] = {
+ {BuiltInId::mod_Float1_Float1,
+ "float mod_emu(float x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float2_Float2,
+ "float2 mod_emu(float2 x, float2 y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float2_Float1,
+ "float2 mod_emu(float2 x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float3_Float3,
+ "float3 mod_emu(float3 x, float3 y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float3_Float1,
+ "float3 mod_emu(float3 x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float4_Float4,
+ "float4 mod_emu(float4 x, float4 y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float4_Float1,
+ "float4 mod_emu(float4 x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::frexp_Float1_Int1,
+ "float frexp_emu(float x, out int exp)\n"
+ "{\n"
+ " float fexp;\n"
+ " float mantissa = frexp(abs(x), fexp) * sign(x);\n"
+ " exp = int(fexp);\n"
+ " return mantissa;\n"
+ "}\n"},
+ {BuiltInId::frexp_Float2_Int2,
+ "float2 frexp_emu(float2 x, out int2 exp)\n"
+ "{\n"
+ " float2 fexp;\n"
+ " float2 mantissa = frexp(abs(x), fexp) * sign(x);\n"
+ " exp = int2(fexp);\n"
+ " return mantissa;\n"
+ "}\n"},
+ {BuiltInId::frexp_Float3_Int3,
+ "float3 frexp_emu(float3 x, out int3 exp)\n"
+ "{\n"
+ " float3 fexp;\n"
+ " float3 mantissa = frexp(abs(x), fexp) * sign(x);\n"
+ " exp = int3(fexp);\n"
+ " return mantissa;\n"
+ "}\n"},
+ {BuiltInId::frexp_Float4_Int4,
+ "float4 frexp_emu(float4 x, out int4 exp)\n"
+ "{\n"
+ " float4 fexp;\n"
+ " float4 mantissa = frexp(abs(x), fexp) * sign(x);\n"
+ " exp = int4(fexp);\n"
+ " return mantissa;\n"
+ "}\n"},
+ {BuiltInId::ldexp_Float1_Int1,
+ "float ldexp_emu(float x, int exp)\n"
+ "{\n"
+ " return ldexp(x, float(exp));\n"
+ "}\n"},
+ {BuiltInId::ldexp_Float2_Int2,
+ "float2 ldexp_emu(float2 x, int2 exp)\n"
+ "{\n"
+ " return ldexp(x, float2(exp));\n"
+ "}\n"},
+ {BuiltInId::ldexp_Float3_Int3,
+ "float3 ldexp_emu(float3 x, int3 exp)\n"
+ "{\n"
+ " return ldexp(x, float3(exp));\n"
+ "}\n"},
+ {BuiltInId::ldexp_Float4_Int4,
+ "float4 ldexp_emu(float4 x, int4 exp)\n"
+ "{\n"
+ " return ldexp(x, float4(exp));\n"
+ "}\n"},
+ {BuiltInId::faceforward_Float1_Float1_Float1,
+ "float faceforward_emu(float N, float I, float Nref)\n"
+ "{\n"
+ " if(dot(Nref, I) >= 0)\n"
+ " {\n"
+ " return -N;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " return N;\n"
+ " }\n"
+ "}\n"},
+ {BuiltInId::faceforward_Float2_Float2_Float2,
+ "float2 faceforward_emu(float2 N, float2 I, float2 Nref)\n"
+ "{\n"
+ " if(dot(Nref, I) >= 0)\n"
+ " {\n"
+ " return -N;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " return N;\n"
+ " }\n"
+ "}\n"},
+ {BuiltInId::faceforward_Float3_Float3_Float3,
+ "float3 faceforward_emu(float3 N, float3 I, float3 Nref)\n"
+ "{\n"
+ " if(dot(Nref, I) >= 0)\n"
+ " {\n"
+ " return -N;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " return N;\n"
+ " }\n"
+ "}\n"},
+ {BuiltInId::faceforward_Float4_Float4_Float4,
+ "float4 faceforward_emu(float4 N, float4 I, float4 Nref)\n"
+ "{\n"
+ " if(dot(Nref, I) >= 0)\n"
+ " {\n"
+ " return -N;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " return N;\n"
+ " }\n"
+ "}\n"},
+ {BuiltInId::atan_Float1_Float1,
+ "float atan_emu(float y, float x)\n"
+ "{\n"
+ " if(x == 0 && y == 0) x = 1;\n"
+ " return atan2(y, x);\n"
+ "}\n"},
+ {BuiltInId::atan_Float2_Float2,
+ "float2 atan_emu(float2 y, float2 x)\n"
+ "{\n"
+ " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
+ " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
+ " return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n"
+ "}\n"},
+ {BuiltInId::atan_Float3_Float3,
+ "float3 atan_emu(float3 y, float3 x)\n"
+ "{\n"
+ " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
+ " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
+ " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
+ " return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n"
+ "}\n"},
+ {BuiltInId::atan_Float4_Float4,
+ "float4 atan_emu(float4 y, float4 x)\n"
+ "{\n"
+ " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
+ " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
+ " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
+ " if(x[3] == 0 && y[3] == 0) x[3] = 1;\n"
+ " return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], \n"
+ " x[2]), atan2(y[3], x[3]));\n"
+ "}\n"},
+ {BuiltInId::asinh_Float1,
+ "float asinh_emu(in float x)\n"
+ "{\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n"},
+ {BuiltInId::asinh_Float2,
+ "float2 asinh_emu(in float2 x)\n"
+ "{\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n"},
+ {BuiltInId::asinh_Float3,
+ "float3 asinh_emu(in float3 x)\n"
+ "{\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n"},
+ {BuiltInId::asinh_Float4,
+ "float4 asinh_emu(in float4 x)\n"
+ "{\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n"},
+ {BuiltInId::acosh_Float1,
+ "float acosh_emu(in float x)\n"
+ "{\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n"},
+ {BuiltInId::acosh_Float2,
+ "float2 acosh_emu(in float2 x)\n"
+ "{\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n"},
+ {BuiltInId::acosh_Float3,
+ "float3 acosh_emu(in float3 x)\n"
+ "{\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n"},
+ {BuiltInId::acosh_Float4,
+ "float4 acosh_emu(in float4 x)\n"
+ "{\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n"},
+ {BuiltInId::atanh_Float1,
+ "float atanh_emu(in float x)\n"
+ "{\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n"},
+ {BuiltInId::atanh_Float2,
+ "float2 atanh_emu(in float2 x)\n"
+ "{\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n"},
+ {BuiltInId::atanh_Float3,
+ "float3 atanh_emu(in float3 x)\n"
+ "{\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n"},
+ {BuiltInId::atanh_Float4,
+ "float4 atanh_emu(in float4 x)\n"
+ "{\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n"},
+ {BuiltInId::roundEven_Float1,
+ "float roundEven_emu(in float x)\n"
+ "{\n"
+ " return (frac(x) == 0.5 && trunc(x) % 2.0 == 0.0) ? trunc(x) : round(x);\n"
+ "}\n"},
+ {BuiltInId::roundEven_Float2,
+ "float2 roundEven_emu(in float2 x)\n"
+ "{\n"
+ " float2 v;\n"
+ " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
+ " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
+ " return v;\n"
+ "}\n"},
+ {BuiltInId::roundEven_Float3,
+ "float3 roundEven_emu(in float3 x)\n"
+ "{\n"
+ " float3 v;\n"
+ " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
+ " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
+ " v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
+ " return v;\n"
+ "}\n"},
+ {BuiltInId::roundEven_Float4,
+ "float4 roundEven_emu(in float4 x)\n"
+ "{\n"
+ " float4 v;\n"
+ " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
+ " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
+ " v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
+ " v[3] = (frac(x[3]) == 0.5 && trunc(x[3]) % 2.0 == 0.0) ? trunc(x[3]) : round(x[3]);\n"
+ " return v;\n"
+ "}\n"},
+ {BuiltInId::packSnorm2x16_Float2,
+ "int webgl_toSnorm16(in float x) {\n"
+ " return int(round(clamp(x, -1.0, 1.0) * 32767.0));\n"
+ "}\n"
+ "uint packSnorm2x16_emu(in float2 v)\n"
+ "{\n"
+ " int x = webgl_toSnorm16(v.x);\n"
+ " int y = webgl_toSnorm16(v.y);\n"
+ " return (asuint(y) << 16) | (asuint(x) & 0xffffu);\n"
+ "}\n"},
+ {BuiltInId::packUnorm2x16_Float2,
+ "uint webgl_toUnorm16(in float x) {\n"
+ " return uint(round(clamp(x, 0.0, 1.0) * 65535.0));\n"
+ "}\n"
+ "uint packUnorm2x16_emu(in float2 v)\n"
+ "{\n"
+ " uint x = webgl_toUnorm16(v.x);\n"
+ " uint y = webgl_toUnorm16(v.y);\n"
+ " return (y << 16) | x;\n"
+ "}\n"},
+ {BuiltInId::packHalf2x16_Float2,
+ "uint packHalf2x16_emu(in float2 v)\n"
+ "{\n"
+ " uint x = f32tof16(v.x);\n"
+ " uint y = f32tof16(v.y);\n"
+ " return (y << 16) | x;\n"
+ "}\n"},
+ {BuiltInId::unpackSnorm2x16_UInt1,
+ "float webgl_fromSnorm16(in uint x) {\n"
+ " int xi = asint(x & 0x7fffu) - asint(x & 0x8000u);\n"
+ " return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
+ "}\n"
+ "float2 unpackSnorm2x16_emu(in uint u)\n"
+ "{\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u;\n"
+ " return float2(webgl_fromSnorm16(x), webgl_fromSnorm16(y));\n"
+ "}\n"},
+ {BuiltInId::unpackUnorm2x16_UInt1,
+ "float webgl_fromUnorm16(in uint x) {\n"
+ " return float(x) / 65535.0;\n"
+ "}\n"
+ "float2 unpackUnorm2x16_emu(in uint u)\n"
+ "{\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u & 0xffffu;\n"
+ " return float2(webgl_fromUnorm16(x), webgl_fromUnorm16(y));\n"
+ "}\n"},
+ {BuiltInId::unpackHalf2x16_UInt1,
+ "float2 unpackHalf2x16_emu(in uint u)\n"
+ "{\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u & 0xffffu;\n"
+ " return float2(f16tof32(x), f16tof32(y));\n"
+ "}\n"},
+ {BuiltInId::packSnorm4x8_Float4,
+ "int webgl_toSnorm8(in float x) {\n"
+ " return int(round(clamp(x, -1.0, 1.0) * 127.0));\n"
+ "}\n"
+ "uint packSnorm4x8_emu(in float4 v)\n"
+ "{\n"
+ " int x = webgl_toSnorm8(v.x);\n"
+ " int y = webgl_toSnorm8(v.y);\n"
+ " int z = webgl_toSnorm8(v.z);\n"
+ " int w = webgl_toSnorm8(v.w);\n"
+ " return ((asuint(w) & 0xffu) << 24) | ((asuint(z) & 0xffu) << 16) \n"
+ " | ((asuint(y) & 0xffu) << 8) | (asuint(x) & 0xffu);\n"
+ "}\n"},
+ {BuiltInId::packUnorm4x8_Float4,
+ "uint webgl_toUnorm8(in float x) {\n"
+ " return uint(round(clamp(x, 0.0, 1.0) * 255.0));\n"
+ "}\n"
+ "uint packUnorm4x8_emu(in float4 v)\n"
+ "{\n"
+ " uint x = webgl_toUnorm8(v.x);\n"
+ " uint y = webgl_toUnorm8(v.y);\n"
+ " uint z = webgl_toUnorm8(v.z);\n"
+ " uint w = webgl_toUnorm8(v.w);\n"
+ " return (w << 24) | (z << 16) | (y << 8) | x;\n"
+ "}\n"},
+ {BuiltInId::unpackSnorm4x8_UInt1,
+ "float webgl_fromSnorm8(in uint x) {\n"
+ " int xi = asint(x & 0x7fu) - asint(x & 0x80u);\n"
+ " return clamp(float(xi) / 127.0, -1.0, 1.0);\n"
+ "}\n"
+ "float4 unpackSnorm4x8_emu(in uint u)\n"
+ "{\n"
+ " uint w = (u >> 24);\n"
+ " uint z = (u >> 16);\n"
+ " uint y = (u >> 8);\n"
+ " uint x = u;\n"
+ " return float4(webgl_fromSnorm8(x), webgl_fromSnorm8(y), \n"
+ " webgl_fromSnorm8(z), webgl_fromSnorm8(w));\n"
+ "}\n"},
+ {BuiltInId::unpackUnorm4x8_UInt1,
+ "float webgl_fromUnorm8(in uint x) {\n"
+ " return float(x) / 255.0;\n"
+ "}\n"
+ "float4 unpackUnorm4x8_emu(in uint u)\n"
+ "{\n"
+ " uint w = (u >> 24) & 0xffu;\n"
+ " uint z = (u >> 16) & 0xffu;\n"
+ " uint y = (u >> 8) & 0xffu;\n"
+ " uint x = u & 0xffu;\n"
+ " return float4(webgl_fromUnorm8(x), webgl_fromUnorm8(y), \n"
+ " webgl_fromUnorm8(z), webgl_fromUnorm8(w));\n"
+ "}\n"},
+ // The matrix resulting from outer product needs to be transposed
+ // (matrices are stored as transposed to simplify element access in HLSL).
+ // So the function should return transpose(c * r) where c is a column vector
+ // and r is a row vector. This can be simplified by using the following
+ // formula:
+ // transpose(c * r) = transpose(r) * transpose(c)
+ // transpose(r) and transpose(c) are in a sense free, since to get the
+ // transpose of r, we simply can build a column matrix out of the original
+ // vector instead of a row matrix.
+ {BuiltInId::outerProduct_Float2_Float2,
+ "float2x2 outerProduct_emu(in float2 c, in float2 r)\n"
+ "{\n"
+ " return mul(float2x1(r), float1x2(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float3_Float3,
+ "float3x3 outerProduct_emu(in float3 c, in float3 r)\n"
+ "{\n"
+ " return mul(float3x1(r), float1x3(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float4_Float4,
+ "float4x4 outerProduct_emu(in float4 c, in float4 r)\n"
+ "{\n"
+ " return mul(float4x1(r), float1x4(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float3_Float2,
+ "float2x3 outerProduct_emu(in float3 c, in float2 r)\n"
+ "{\n"
+ " return mul(float2x1(r), float1x3(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float2_Float3,
+ "float3x2 outerProduct_emu(in float2 c, in float3 r)\n"
+ "{\n"
+ " return mul(float3x1(r), float1x2(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float4_Float2,
+ "float2x4 outerProduct_emu(in float4 c, in float2 r)\n"
+ "{\n"
+ " return mul(float2x1(r), float1x4(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float2_Float4,
+ "float4x2 outerProduct_emu(in float2 c, in float4 r)\n"
+ "{\n"
+ " return mul(float4x1(r), float1x2(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float4_Float3,
+ "float3x4 outerProduct_emu(in float4 c, in float3 r)\n"
+ "{\n"
+ " return mul(float3x1(r), float1x4(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float3_Float4,
+ "float4x3 outerProduct_emu(in float3 c, in float4 r)\n"
+ "{\n"
+ " return mul(float4x1(r), float1x3(c));\n"
+ "}\n"},
+ // Remember here that the parameter matrix is actually the transpose
+ // of the matrix that we're trying to invert, and the resulting matrix
+ // should also be the transpose of the inverse.
+ // When accessing the parameter matrix with m[a][b] it can be thought of so
+ // that a is the column and b is the row of the matrix that we're inverting.
+ // We calculate the inverse as the adjugate matrix divided by the
+ // determinant of the matrix being inverted. However, as the result needs
+ // to be transposed, we actually use of the transpose of the adjugate matrix
+ // which happens to be the cofactor matrix. That's stored in 'cof'.
+ // We don't need to care about divide-by-zero since results are undefined
+ // for singular or poorly-conditioned matrices.
+ {BuiltInId::inverse_Float2x2,
+ "float2x2 inverse_emu(in float2x2 m)\n"
+ "{\n"
+ " float2x2 cof = { m[1][1], -m[0][1], -m[1][0], m[0][0] };\n"
+ " return cof / determinant(transpose(m));\n"
+ "}\n"},
+ // cofAB is the cofactor for column A and row B.
+ {BuiltInId::inverse_Float3x3,
+ "float3x3 inverse_emu(in float3x3 m)\n"
+ "{\n"
+ " float cof00 = m[1][1] * m[2][2] - m[2][1] * m[1][2];\n"
+ " float cof01 = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]);\n"
+ " float cof02 = m[1][0] * m[2][1] - m[2][0] * m[1][1];\n"
+ " float cof10 = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]);\n"
+ " float cof11 = m[0][0] * m[2][2] - m[2][0] * m[0][2];\n"
+ " float cof12 = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]);\n"
+ " float cof20 = m[0][1] * m[1][2] - m[1][1] * m[0][2];\n"
+ " float cof21 = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]);\n"
+ " float cof22 = m[0][0] * m[1][1] - m[1][0] * m[0][1];\n"
+ " float3x3 cof = { cof00, cof10, cof20, cof01, cof11, cof21, cof02, cof12, cof22 };\n"
+ " return cof / determinant(transpose(m));\n"
+ "}\n"},
+ {BuiltInId::inverse_Float4x4,
+ "float4x4 inverse_emu(in float4x4 m)\n"
+ "{\n"
+ " float cof00 = m[1][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[1][3] + m[3][1] * \n"
+ " m[1][2] * m[2][3]\n"
+ " - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] - m[3][1] * m[2][2] * \n"
+ " m[1][3];\n"
+ " float cof01 = -(m[1][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[1][3] + m[3][0] * \n"
+ " m[1][2] * m[2][3]\n"
+ " - m[1][0] * m[3][2] * m[2][3] - m[2][0] * m[1][2] * m[3][3] - m[3][0] * m[2][2] * \n"
+ " m[1][3]);\n"
+ " float cof02 = m[1][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[1][3] + m[3][0] * \n"
+ " m[1][1] * m[2][3]\n"
+ " - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] - m[3][0] * m[2][1] * \n"
+ " m[1][3];\n"
+ " float cof03 = -(m[1][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[1][2] + m[3][0] * \n"
+ " m[1][1] * m[2][2]\n"
+ " - m[1][0] * m[3][1] * m[2][2] - m[2][0] * m[1][1] * m[3][2] - m[3][0] * m[2][1] * \n"
+ " m[1][2]);\n"
+ " float cof10 = -(m[0][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[0][3] + m[3][1] * \n"
+ " m[0][2] * m[2][3]\n"
+ " - m[0][1] * m[3][2] * m[2][3] - m[2][1] * m[0][2] * m[3][3] - m[3][1] * m[2][2] * \n"
+ " m[0][3]);\n"
+ " float cof11 = m[0][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[0][3] + m[3][0] * \n"
+ " m[0][2] * m[2][3]\n"
+ " - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] - m[3][0] * m[2][2] * \n"
+ " m[0][3];\n"
+ " float cof12 = -(m[0][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[0][3] + m[3][0] * \n"
+ " m[0][1] * m[2][3]\n"
+ " - m[0][0] * m[3][1] * m[2][3] - m[2][0] * m[0][1] * m[3][3] - m[3][0] * m[2][1] * \n"
+ " m[0][3]);\n"
+ " float cof13 = m[0][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[0][2] + m[3][0] * \n"
+ " m[0][1] * m[2][2]\n"
+ " - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] - m[3][0] * m[2][1] * \n"
+ " m[0][2];\n"
+ " float cof20 = m[0][1] * m[1][2] * m[3][3] + m[1][1] * m[3][2] * m[0][3] + m[3][1] * \n"
+ " m[0][2] * m[1][3]\n"
+ " - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] - m[3][1] * m[1][2] * \n"
+ " m[0][3];\n"
+ " float cof21 = -(m[0][0] * m[1][2] * m[3][3] + m[1][0] * m[3][2] * m[0][3] + m[3][0] * \n"
+ " m[0][2] * m[1][3]\n"
+ " - m[0][0] * m[3][2] * m[1][3] - m[1][0] * m[0][2] * m[3][3] - m[3][0] * m[1][2] * \n"
+ " m[0][3]);\n"
+ " float cof22 = m[0][0] * m[1][1] * m[3][3] + m[1][0] * m[3][1] * m[0][3] + m[3][0] * \n"
+ " m[0][1] * m[1][3]\n"
+ " - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] - m[3][0] * m[1][1] * \n"
+ " m[0][3];\n"
+ " float cof23 = -(m[0][0] * m[1][1] * m[3][2] + m[1][0] * m[3][1] * m[0][2] + m[3][0] * \n"
+ " m[0][1] * m[1][2]\n"
+ " - m[0][0] * m[3][1] * m[1][2] - m[1][0] * m[0][1] * m[3][2] - m[3][0] * m[1][1] * \n"
+ " m[0][2]);\n"
+ " float cof30 = -(m[0][1] * m[1][2] * m[2][3] + m[1][1] * m[2][2] * m[0][3] + m[2][1] * \n"
+ " m[0][2] * m[1][3]\n"
+ " - m[0][1] * m[2][2] * m[1][3] - m[1][1] * m[0][2] * m[2][3] - m[2][1] * m[1][2] * \n"
+ " m[0][3]);\n"
+ " float cof31 = m[0][0] * m[1][2] * m[2][3] + m[1][0] * m[2][2] * m[0][3] + m[2][0] * \n"
+ " m[0][2] * m[1][3]\n"
+ " - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] - m[2][0] * m[1][2] * \n"
+ " m[0][3];\n"
+ " float cof32 = -(m[0][0] * m[1][1] * m[2][3] + m[1][0] * m[2][1] * m[0][3] + m[2][0] * \n"
+ " m[0][1] * m[1][3]\n"
+ " - m[0][0] * m[2][1] * m[1][3] - m[1][0] * m[0][1] * m[2][3] - m[2][0] * m[1][1] * \n"
+ " m[0][3]);\n"
+ " float cof33 = m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[2][0] * \n"
+ " m[0][1] * m[1][2]\n"
+ " - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] - m[2][0] * m[1][1] * \n"
+ " m[0][2];\n"
+ " float4x4 cof = { cof00, cof10, cof20, cof30, cof01, cof11, cof21, cof31,\n"
+ " cof02, cof12, cof22, cof32, cof03, cof13, cof23, cof33 };\n"
+ " return cof / determinant(transpose(m));\n"
+ "}\n"},
+ // Emulate ESSL3 variant of mix that takes last argument as boolean vector.
+ // genType mix(genType x, genType y, genBType a): Selects which vector each returned component
+ // comes from. For a component of 'a' that is false, the corresponding component of 'x' is
+ // returned. For a component of 'a' that is true, the corresponding component of 'y' is
+ // returned.
+ {BuiltInId::mix_Float1_Float1_Bool1,
+ "float mix_emu(float x, float y, bool a)\n"
+ "{\n"
+ " return a ? y : x;\n"
+ "}\n"},
+ {BuiltInId::mix_Float2_Float2_Bool2,
+ "float2 mix_emu(float2 x, float2 y, bool2 a)\n"
+ "{\n"
+ " return a ? y : x;\n"
+ "}\n"},
+ {BuiltInId::mix_Float3_Float3_Bool3,
+ "float3 mix_emu(float3 x, float3 y, bool3 a)\n"
+ "{\n"
+ " return a ? y : x;\n"
+ "}\n"},
+ {BuiltInId::mix_Float4_Float4_Bool4,
+ "float4 mix_emu(float4 x, float4 y, bool4 a)\n"
+ "{\n"
+ " return a ? y : x;\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_UInt1_Int1_Int1,
+ "uint bitfieldExtract_emu(uint value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return 0u;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " return (value & mask) >> offset;\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_UInt2_Int1_Int1,
+ "uint2 bitfieldExtract_emu(uint2 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return uint2(0u, 0u);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " return (value & mask) >> offset;\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_UInt3_Int1_Int1,
+ "uint3 bitfieldExtract_emu(uint3 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return uint3(0u, 0u, 0u);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " return (value & mask) >> offset;\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_UInt4_Int1_Int1,
+ "uint4 bitfieldExtract_emu(uint4 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return uint4(0u, 0u, 0u, 0u);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " return (value & mask) >> offset;\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_Int1_Int1_Int1,
+ "int bitfieldExtract_emu(int value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return 0;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint resultUnsigned = (asuint(value) & mask) >> offset;\n"
+ " if (bits != 32 && (resultUnsigned & maskMsb) != 0)\n"
+ " {\n"
+ " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
+ " resultUnsigned |= higherBitsMask;\n"
+ " }\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_Int2_Int1_Int1,
+ "int2 bitfieldExtract_emu(int2 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return int2(0, 0);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint2 resultUnsigned = (asuint(value) & mask) >> offset;\n"
+ " if (bits != 32)\n"
+ " {\n"
+ " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
+ " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n"
+ " }\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_Int3_Int1_Int1,
+ "int3 bitfieldExtract_emu(int3 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return int3(0, 0, 0);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint3 resultUnsigned = (asuint(value) & mask) >> offset;\n"
+ " if (bits != 32)\n"
+ " {\n"
+ " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
+ " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n"
+ " }\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_Int4_Int1_Int1,
+ "int4 bitfieldExtract_emu(int4 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return int4(0, 0, 0, 0);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint4 resultUnsigned = (asuint(value) & mask) >> offset;\n"
+ " if (bits != 32)\n"
+ " {\n"
+ " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
+ " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n"
+ " }\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_UInt1_UInt1_Int1_Int1,
+ "uint bitfieldInsert_emu(uint base, uint insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " return (base & baseMask) | ((insert << offset) & insertMask);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_UInt2_UInt2_Int1_Int1,
+ "uint2 bitfieldInsert_emu(uint2 base, uint2 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " return (base & baseMask) | ((insert << offset) & insertMask);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_UInt3_UInt3_Int1_Int1,
+ "uint3 bitfieldInsert_emu(uint3 base, uint3 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " return (base & baseMask) | ((insert << offset) & insertMask);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_UInt4_UInt4_Int1_Int1,
+ "uint4 bitfieldInsert_emu(uint4 base, uint4 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " return (base & baseMask) | ((insert << offset) & insertMask);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_Int1_Int1_Int1_Int1,
+ "int bitfieldInsert_emu(int base, int insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " uint resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
+ " insertMask);\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_Int2_Int2_Int1_Int1,
+ "int2 bitfieldInsert_emu(int2 base, int2 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " uint2 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
+ " insertMask);\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_Int3_Int3_Int1_Int1,
+ "int3 bitfieldInsert_emu(int3 base, int3 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " uint3 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
+ " insertMask);\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_Int4_Int4_Int1_Int1,
+ "int4 bitfieldInsert_emu(int4 base, int4 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " uint4 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
+ " insertMask);\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::uaddCarry_UInt1_UInt1_UInt1,
+ "uint uaddCarry_emu(uint x, uint y, out uint carry)\n"
+ "{\n"
+ " carry = uint(x > (0xffffffffu - y));\n"
+ " return x + y;\n"
+ "}\n"},
+ {BuiltInId::uaddCarry_UInt2_UInt2_UInt2,
+ "uint2 uaddCarry_emu(uint2 x, uint2 y, out uint2 carry)\n"
+ "{\n"
+ " carry = uint2(x > (0xffffffffu - y));\n"
+ " return x + y;\n"
+ "}\n"},
+ {BuiltInId::uaddCarry_UInt3_UInt3_UInt3,
+ "uint3 uaddCarry_emu(uint3 x, uint3 y, out uint3 carry)\n"
+ "{\n"
+ " carry = uint3(x > (0xffffffffu - y));\n"
+ " return x + y;\n"
+ "}\n"},
+ {BuiltInId::uaddCarry_UInt4_UInt4_UInt4,
+ "uint4 uaddCarry_emu(uint4 x, uint4 y, out uint4 carry)\n"
+ "{\n"
+ " carry = uint4(x > (0xffffffffu - y));\n"
+ " return x + y;\n"
+ "}\n"},
+ {BuiltInId::usubBorrow_UInt1_UInt1_UInt1,
+ "uint usubBorrow_emu(uint x, uint y, out uint borrow)\n"
+ "{\n"
+ " borrow = uint(x < y);\n"
+ " return x - y;\n"
+ "}\n"},
+ {BuiltInId::usubBorrow_UInt2_UInt2_UInt2,
+ "uint2 usubBorrow_emu(uint2 x, uint2 y, out uint2 borrow)\n"
+ "{\n"
+ " borrow = uint2(x < y);\n"
+ " return x - y;\n"
+ "}\n"},
+ {BuiltInId::usubBorrow_UInt3_UInt3_UInt3,
+ "uint3 usubBorrow_emu(uint3 x, uint3 y, out uint3 borrow)\n"
+ "{\n"
+ " borrow = uint3(x < y);\n"
+ " return x - y;\n"
+ "}\n"},
+ {BuiltInId::usubBorrow_UInt4_UInt4_UInt4,
+ "uint4 usubBorrow_emu(uint4 x, uint4 y, out uint4 borrow)\n"
+ "{\n"
+ " borrow = uint4(x < y);\n"
+ " return x - y;\n"
+ "}\n"},
+ // We emulate tanh just to avoid overflow on large arguments.
+ {BuiltInId::tanh_Float1,
+ "float tanh_emu(float x)\n"
+ "{\n"
+ " return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
+ "}\n"},
+ {BuiltInId::tanh_Float2,
+ "float2 tanh_emu(float2 x)\n"
+ "{\n"
+ " return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
+ "}\n"},
+ {BuiltInId::tanh_Float3,
+ "float3 tanh_emu(float3 x)\n"
+ "{\n"
+ " return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
+ "}\n"},
+ {BuiltInId::tanh_Float4,
+ "float4 tanh_emu(float4 x)\n"
+ "{\n"
+ " return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
+ "}\n"},
+};
+} // anonymous namespace
+
+const char *FindHLSLFunction(int uniqueId)
+{
+ for (size_t index = 0; index < ArraySize(g_hlslFunctions); ++index)
+ {
+ const auto &function = g_hlslFunctions[index];
+ if (function.id == uniqueId)
+ {
+ return function.body;
+ }
+ }
+
+ return nullptr;
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/glslang.h b/gfx/angle/checkout/src/compiler/translator/glslang.h
new file mode 100644
index 0000000000..301da81cca
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/glslang.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_GLSLANG_H_
+#define COMPILER_TRANSLATOR_GLSLANG_H_
+
+namespace sh
+{
+class TParseContext;
+}
+
+extern int glslang_initialize(sh::TParseContext *context);
+extern int glslang_finalize(sh::TParseContext *context);
+
+extern int glslang_scan(size_t count,
+ const char *const string[],
+ const int length[],
+ sh::TParseContext *context);
+extern int glslang_parse(sh::TParseContext *context);
+
+#endif // COMPILER_TRANSLATOR_GLSLANG_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/glslang_lex_autogen.cpp b/gfx/angle/checkout/src/compiler/translator/glslang_lex_autogen.cpp
new file mode 100644
index 0000000000..c806fd8e3a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/glslang_lex_autogen.cpp
@@ -0,0 +1,4326 @@
+#line 17 "glslang.l"
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_parser.py from glslang.l
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// glslang.l:
+// Lexer for the OpenGL shading language.
+
+// Ignore errors in auto-generated code.
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wswitch-enum"
+# pragma GCC diagnostic ignored "-Wunused-function"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+#elif defined(_MSC_VER)
+# pragma warning(disable : 4005)
+# pragma warning(disable : 4065)
+# pragma warning(disable : 4189)
+# pragma warning(disable : 4244)
+# pragma warning(disable : 4505)
+# pragma warning(disable : 4701)
+# pragma warning(disable : 4702)
+#endif
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
+# if defined(__APPLE__)
+// Older clang versions don't have -Wextra-semi-stmt, and detecting Apple clang versions is
+// difficult because they use different yet overlapping version numbers vs. regular clang.
+# pragma clang diagnostic ignored "-Wunknown-warning-option"
+# endif
+// Flex isn't semi-colon clean.
+# pragma clang diagnostic ignored "-Wextra-semi-stmt"
+# pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 4
+#if YY_FLEX_SUBMINOR_VERSION > 0
+# define FLEX_BETA
+#endif
+
+#ifdef yyget_lval
+# define yyget_lval_ALREADY_DEFINED
+#else
+# define yyget_lval yyget_lval
+#endif
+
+#ifdef yyset_lval
+# define yyset_lval_ALREADY_DEFINED
+#else
+# define yyset_lval yyset_lval
+#endif
+
+#ifdef yyget_lloc
+# define yyget_lloc_ALREADY_DEFINED
+#else
+# define yyget_lloc yyget_lloc
+#endif
+
+#ifdef yyset_lloc
+# define yyset_lloc_ALREADY_DEFINED
+#else
+# define yyset_lloc yyset_lloc
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+# define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+# ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS 1
+# endif
+
+# include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+# else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+# ifndef INT8_MIN
+# define INT8_MIN (-128)
+# endif
+# ifndef INT16_MIN
+# define INT16_MIN (-32767 - 1)
+# endif
+# ifndef INT32_MIN
+# define INT32_MIN (-2147483647 - 1)
+# endif
+# ifndef INT8_MAX
+# define INT8_MAX (127)
+# endif
+# ifndef INT16_MAX
+# define INT16_MAX (32767)
+# endif
+# ifndef INT32_MAX
+# define INT32_MAX (2147483647)
+# endif
+# ifndef UINT8_MAX
+# define UINT8_MAX (255U)
+# endif
+# ifndef UINT16_MAX
+# define UINT16_MAX (65535U)
+# endif
+# ifndef UINT32_MAX
+# define UINT32_MAX (4294967295U)
+# endif
+
+# ifndef SIZE_MAX
+# define SIZE_MAX (~(size_t)0)
+# endif
+
+# endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+# define yynoreturn __attribute__((__noreturn__))
+#else
+# define yynoreturn
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
+ */
+#define YY_SC_TO_UI(c) ((YY_CHAR)(c))
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+# define YY_TYPEDEF_YY_SCANNER_T
+typedef void *yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin, yyscanner)
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+# ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+# define YY_BUF_SIZE 32768
+# else
+# define YY_BUF_SIZE 16384
+# endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+# define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+# define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+ * access to the local variable yy_act. Since yyless() is a macro, it would break
+ * existing scanners that call yyless() from OUTSIDE yylex.
+ * One obvious solution it to make yy_act a global. I tried that, and saw
+ * a 5% performance hit in a non-yylineno scanner, because yy_act is
+ * normally declared as a register variable-- so it is not worth it.
+ */
+#define YY_LESS_LINENO(n) \
+ do \
+ { \
+ int yyl; \
+ for (yyl = n; yyl < yyleng; ++yyl) \
+ if (yytext[yyl] == '\n') \
+ --yylineno; \
+ } while (0)
+#define YY_LINENO_REWIND_TO(dst) \
+ do \
+ { \
+ const char *p; \
+ for (p = yy_cp - 1; p >= (dst); --p) \
+ if (*p == '\n') \
+ --yylineno; \
+ } while (0)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg); \
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } while (0)
+#define unput(c) yyunput(c, yyg->yytext_ptr, yyscanner)
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+# define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+{
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+# define YY_BUFFER_NEW 0
+# define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+# define YY_BUFFER_EOF_PENDING 2
+};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER \
+ (yyg->yy_buffer_stack ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] : NULL)
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void yyrestart(FILE *input_file, yyscan_t yyscanner);
+void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner);
+YY_BUFFER_STATE yy_create_buffer(FILE *file, int size, yyscan_t yyscanner);
+void yy_delete_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner);
+void yy_flush_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner);
+void yypush_buffer_state(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner);
+void yypop_buffer_state(yyscan_t yyscanner);
+
+static void yyensure_buffer_stack(yyscan_t yyscanner);
+static void yy_load_buffer_state(yyscan_t yyscanner);
+static void yy_init_buffer(YY_BUFFER_STATE b, FILE *file, yyscan_t yyscanner);
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER, yyscanner)
+
+YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size, yyscan_t yyscanner);
+YY_BUFFER_STATE yy_scan_string(const char *yy_str, yyscan_t yyscanner);
+YY_BUFFER_STATE yy_scan_bytes(const char *bytes, int len, yyscan_t yyscanner);
+
+void *yyalloc(yy_size_t, yyscan_t yyscanner);
+void *yyrealloc(void *, yy_size_t, yyscan_t yyscanner);
+void yyfree(void *, yyscan_t yyscanner);
+
+#define yy_new_buffer yy_create_buffer
+#define yy_set_interactive(is_interactive) \
+ { \
+ if (!YY_CURRENT_BUFFER) \
+ { \
+ yyensure_buffer_stack(yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+#define yy_set_bol(at_bol) \
+ { \
+ if (!YY_CURRENT_BUFFER) \
+ { \
+ yyensure_buffer_stack(yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap(yyscanner) (/*CONSTCOND*/ 1)
+#define YY_SKIP_YYWRAP
+typedef flex_uint8_t YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state(yyscan_t yyscanner);
+static yy_state_type yy_try_NUL_trans(yy_state_type current_state, yyscan_t yyscanner);
+static int yy_get_next_buffer(yyscan_t yyscanner);
+static void yynoreturn yy_fatal_error(const char *msg, yyscan_t yyscanner);
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+ yyleng = (int)(yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
+#define YY_NUM_RULES 259
+#define YY_END_OF_BUFFER 260
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+{
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+};
+static const flex_int16_t yy_accept[982] = {
+ 0, 0, 0, 0, 0, 260, 258, 257, 257, 241, 247, 252, 236, 237, 245, 244, 233,
+ 242, 240, 246, 199, 199, 234, 230, 248, 235, 249, 253, 196, 238, 239, 251, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 231, 250, 232, 243, 256, 255, 259, 254, 227, 213, 232, 221, 216, 211,
+ 219, 209, 220, 210, 205, 212, 204, 198, 199, 0, 202, 0, 239, 231, 238, 228, 224,
+ 226, 225, 229, 196, 217, 223, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+
+ 196, 196, 196, 196, 13, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 16, 196, 196, 26, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 218, 222, 254, 0, 208, 204, 0, 207,
+ 201, 0, 203, 197, 214, 215, 196, 196, 156, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+
+ 196, 14, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 31, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 27, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 0, 205, 0,
+ 204, 206, 200, 196, 196, 196, 196, 34, 196, 196, 196, 19, 193, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 17, 159, 196, 196, 196, 196, 22, 196, 196,
+
+ 163, 174, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 171,
+ 4, 39, 40, 41, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 162, 35, 196, 196,
+ 32, 196, 196, 196, 196, 196, 196, 196, 196, 51, 52, 53, 33, 196, 196, 196, 196,
+ 196, 196, 196, 196, 11, 196, 57, 58, 59, 196, 157, 196, 196, 7, 196, 196, 196,
+ 196, 183, 184, 185, 196, 36, 196, 175, 30, 186, 187, 188, 2, 180, 181,
+
+ 182, 196, 196, 196, 28, 178, 196, 196, 196, 196, 196, 196, 54, 55, 56, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 25, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 172, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 158, 196, 196,
+ 196, 195, 60, 61, 62, 196, 196, 15, 196, 196, 196, 135, 196, 196, 9, 196, 196,
+ 133, 196, 196, 196, 173, 168, 136, 196, 196, 196, 196, 196, 196, 164, 196, 196, 196,
+ 196, 196, 196, 97, 42, 45, 47, 46, 43, 49, 48, 50, 44, 196, 196,
+
+ 196, 196, 179, 155, 196, 196, 196, 166, 196, 196, 196, 38, 126, 29, 192, 23, 167,
+ 96, 196, 177, 18, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 20, 37, 196, 196, 196, 196, 196, 196, 137, 102, 108, 196, 196,
+ 196, 196, 196, 196, 99, 101, 3, 196, 196, 196, 196, 196, 127, 196, 196, 196, 196,
+ 196, 196, 196, 160, 196, 196, 196, 196, 196, 8, 196, 196, 196, 10, 196, 196, 196,
+ 196, 196, 196, 21, 122, 12, 169, 138, 103, 110, 196, 196, 196, 196, 196,
+
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 165, 196, 196, 196, 196, 120, 131, 123,
+ 196, 196, 196, 196, 196, 196, 196, 196, 161, 139, 104, 109, 196, 196, 176, 196, 196,
+ 124, 196, 196, 196, 196, 6, 196, 196, 196, 196, 196, 196, 196, 196, 196, 113, 170,
+ 1, 196, 196, 196, 196, 196, 196, 196, 194, 196, 134, 196, 5, 189, 63, 66, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 121, 196, 196,
+ 196, 196, 196, 196, 111, 196, 196, 196, 196, 196, 196, 196, 149, 71, 72,
+
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 132,
+ 196, 196, 196, 112, 196, 151, 76, 77, 196, 196, 196, 196, 125, 196, 196, 196, 196,
+ 196, 196, 196, 196, 117, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 70, 196, 196, 196, 196, 64, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 118, 196, 140, 196, 105, 196, 196, 196, 196,
+ 196, 75, 196, 196, 73, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+
+ 196, 196, 196, 196, 196, 196, 196, 119, 196, 196, 196, 196, 80, 196, 196, 78, 196,
+ 196, 141, 106, 196, 196, 143, 196, 144, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 24, 196, 196, 196, 196, 196, 68, 196, 67, 89, 196, 196, 196, 196, 142, 107, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 114, 196, 196, 196, 196,
+ 153, 92, 196, 196, 196, 147, 196, 69, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 154, 94, 196, 196, 196, 115, 196, 196, 196, 150, 74, 196,
+
+ 196, 196, 128, 196, 190, 196, 196, 196, 81, 196, 196, 196, 196, 116, 196, 152, 79,
+ 196, 196, 196, 196, 196, 196, 129, 196, 196, 196, 196, 196, 85, 196, 88, 196, 196,
+ 196, 130, 196, 196, 196, 196, 196, 196, 86, 91, 196, 196, 196, 196, 196, 82, 196,
+ 95, 87, 93, 98, 196, 145, 146, 100, 196, 196, 196, 196, 65, 196, 196, 196, 191,
+ 196, 196, 148, 83, 196, 196, 196, 196, 90, 196, 196, 84, 0};
+
+static const YY_CHAR yy_ec[256] = {
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 1, 1, 1, 5, 6, 1, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 1, 31, 32, 33, 34, 35, 36, 37, 38, 38, 38, 38, 39, 40, 41, 42, 38, 38, 43, 44,
+ 45, 46, 47, 48, 49, 50, 38, 51, 1, 52, 53, 54, 1, 55, 56, 57, 58,
+
+ 59, 60, 61, 62, 63, 38, 64, 65, 66, 67, 68, 69, 38, 70, 71, 72, 73, 74, 75, 76, 77,
+ 78, 79, 80, 81, 82, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+
+static const YY_CHAR yy_meta[83] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 3, 5, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 7, 6, 6, 6, 6, 1, 1, 1, 6, 4, 4, 4, 4, 3, 5, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 1, 1, 1, 1};
+
+static const flex_int16_t yy_base[988] = {
+ 0, 0, 0, 82, 0, 1237, 1238, 1238, 1238, 1208, 137, 161, 1238, 1238, 1207,
+ 158, 1238, 157, 155, 1206, 177, 168, 1204, 1238, 177, 1204, 155, 1238, 0, 1238,
+ 1238, 160, 1177, 149, 160, 170, 148, 143, 177, 1162, 184, 194, 163, 132, 169,
+ 1156, 189, 1169, 209, 208, 220, 218, 147, 1154, 1238, 215, 1238, 1238, 1238, 1238,
+ 1238, 0, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 220, 1238, 257,
+ 250, 263, 322, 1238, 0, 1238, 1238, 1238, 1198, 1238, 1238, 1238, 1197, 0, 1238,
+ 1238, 1153, 1151, 1156, 229, 1153, 1161, 1159, 1159, 1146, 1149,
+
+ 1160, 238, 1154, 1142, 1139, 1152, 1139, 1136, 1136, 1142, 237, 235, 1136, 1146, 1132,
+ 1138, 1141, 1142, 0, 1134, 1144, 246, 1135, 1142, 1123, 1136, 1117, 252, 1121, 1134,
+ 1125, 243, 1118, 278, 1113, 1129, 1131, 253, 1120, 292, 1107, 1116, 294, 296, 1120,
+ 1116, 1118, 1107, 1110, 182, 258, 1115, 296, 1118, 1106, 1118, 265, 1111, 1110, 1098,
+ 1238, 1238, 0, 351, 1238, 318, 369, 1238, 1238, 379, 389, 285, 1238, 1238, 1116,
+ 1107, 0, 1103, 1098, 1102, 1111, 1105, 1107, 355, 1091, 1091, 1102, 1094, 284, 1104,
+ 1101, 1101, 1099, 1096, 1088, 1094, 1081, 1079, 1091, 1077,
+
+ 1093, 0, 1090, 1078, 1085, 1082, 1086, 1087, 1080, 1077, 1066, 1065, 1078, 1081, 1059,
+ 1068, 1079, 1075, 1063, 1069, 1060, 398, 1065, 1068, 1059, 1066, 1055, 1059, 1050, 1064,
+ 1061, 1062, 1053, 1059, 308, 1043, 1046, 1044, 1043, 1053, 1043, 1038, 1036, 1038, 1048,
+ 1034, 1036, 1033, 1044, 1043, 1046, 1028, 358, 1036, 1022, 1031, 1029, 1038, 1017, 402,
+ 1035, 1037, 1026, 1018, 1056, 413, 423, 445, 455, 1238, 1238, 1022, 1013, 1023, 1022,
+ 0, 1020, 1024, 405, 0, 0, 1012, 1010, 1010, 1011, 1006, 1014, 1003, 1020, 1009,
+ 433, 0, 0, 1003, 1013, 1012, 1012, 0, 997, 436,
+
+ 0, 0, 999, 439, 1006, 1007, 998, 992, 991, 992, 991, 1001, 990, 361, 463,
+ 985, 0, 0, 981, 980, 979, 981, 982, 987, 981, 977, 990, 985, 985, 981,
+ 982, 981, 975, 969, 971, 970, 974, 979, 965, 968, 963, 971, 976, 964, 961,
+ 973, 964, 0, 0, 970, 966, 0, 958, 958, 963, 964, 953, 960, 467, 957,
+ 0, 0, 0, 0, 947, 959, 958, 945, 946, 955, 956, 956, 0, 941, 0,
+ 0, 0, 942, 0, 950, 941, 0, 940, 941, 935, 945, 0, 0, 0, 936,
+ 0, 932, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 942, 471, 941, 0, 0, 939, 935, 932, 931, 980, 979, 0, 0, 0,
+ 921, 475, 478, 481, 926, 922, 927, 918, 916, 929, 914, 0, 946, 913, 926,
+ 915, 911, 917, 912, 919, 919, 0, 916, 913, 917, 901, 899, 902, 908, 914,
+ 909, 908, 896, 0, 898, 899, 898, 0, 0, 0, 0, 895, 898, 0, 892,
+ 902, 893, 0, 903, 883, 0, 892, 887, 0, 880, 880, 893, 0, 895, 0,
+ 489, 915, 914, 913, 873, 872, 0, 889, 888, 903, 882, 924, 915, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 869, 882,
+
+ 869, 866, 0, 0, 871, 865, 449, 0, 867, 874, 873, 0, 859, 0, 0,
+ 0, 0, 0, 856, 0, 0, 855, 866, 493, 859, 865, 884, 863, 860, 855,
+ 852, 874, 858, 843, 843, 856, 841, 853, 0, 0, 846, 876, 875, 874, 834,
+ 833, 470, 485, 0, 845, 848, 846, 835, 833, 830, 845, 0, 0, 841, 838,
+ 837, 827, 837, 0, 825, 815, 832, 818, 501, 826, 829, 0, 853, 852, 851,
+ 811, 810, 0, 824, 813, 810, 0, 820, 813, 805, 806, 812, 815, 0, 0,
+ 0, 0, 842, 841, 0, 811, 814, 799, 806, 797,
+
+ 804, 805, 805, 804, 790, 804, 514, 800, 800, 0, 801, 790, 801, 788, 0,
+ 0, 0, 820, 819, 818, 778, 777, 773, 785, 780, 0, 815, 814, 0, 784,
+ 787, 0, 785, 521, 0, 764, 785, 804, 771, 0, 767, 766, 775, 775, 763,
+ 777, 761, 775, 770, 797, 0, 0, 772, 792, 791, 790, 750, 749, 748, 0,
+ 748, 0, 754, 0, 496, 512, 775, 757, 760, 743, 756, 754, 742, 741, 750,
+ 750, 753, 773, 772, 771, 731, 730, 0, 735, 725, 728, 729, 728, 738, 765,
+ 740, 736, 738, 734, 721, 720, 724, 757, 518, 0,
+
+ 727, 730, 720, 721, 752, 712, 719, 710, 735, 719, 715, 717, 715, 715, 714,
+ 713, 0, 701, 700, 710, 737, 702, 735, 519, 0, 705, 708, 705, 690, 0,
+ 706, 705, 689, 688, 680, 688, 678, 686, 0, 683, 721, 681, 680, 705, 689,
+ 687, 687, 680, 670, 698, 666, 668, 652, 690, 123, 160, 189, 210, 497, 204,
+ 220, 252, 255, 263, 287, 331, 378, 420, 458, 454, 460, 464, 469, 476, 465,
+ 467, 0, 475, 507, 482, 516, 488, 509, 524, 496, 497, 537, 512, 511, 540,
+ 518, 514, 537, 520, 518, 522, 508, 507, 522, 509,
+
+ 512, 513, 522, 518, 538, 510, 511, 0, 519, 549, 521, 522, 562, 537, 536,
+ 565, 527, 528, 0, 0, 544, 538, 0, 539, 0, 525, 566, 549, 550, 536,
+ 535, 538, 539, 540, 0, 572, 535, 545, 537, 545, 572, 549, 0, 0, 548,
+ 564, 565, 586, 0, 0, 567, 586, 569, 570, 556, 555, 558, 559, 572, 564,
+ 555, 578, 579, 0, 596, 559, 560, 568, 0, 0, 569, 585, 606, 598, 568,
+ 600, 590, 584, 572, 593, 591, 585, 619, 575, 614, 577, 578, 586, 0, 0,
+ 587, 623, 604, 0, 602, 603, 627, 0, 0, 608,
+
+ 609, 598, 0, 604, 0, 605, 591, 614, 0, 593, 603, 630, 636, 0, 639,
+ 0, 0, 620, 621, 628, 613, 611, 612, 0, 604, 605, 622, 629, 630, 0,
+ 628, 643, 613, 654, 651, 0, 614, 615, 648, 677, 620, 621, 0, 0, 638,
+ 640, 641, 632, 639, 0, 658, 0, 0, 0, 0, 669, 0, 0, 0, 636,
+ 637, 631, 652, 0, 658, 634, 635, 0, 653, 695, 0, 0, 645, 664, 640,
+ 681, 0, 668, 673, 0, 1238, 717, 722, 727, 732, 735, 738};
+
+static const flex_int16_t yy_def[988] = {
+ 0, 981, 1, 981, 3, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 982, 981, 981, 981, 981, 981, 981, 983, 981, 981, 981, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 981, 981, 981, 981, 981, 981, 981, 984, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 985, 981, 986, 20, 982, 981, 981, 987, 981, 981, 981, 981, 981, 981, 981, 981, 983, 981,
+ 981, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 981, 981, 984, 981, 981, 986, 981, 981, 981, 981, 981, 987,
+ 981, 981, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 981, 981, 981, 981, 981, 981, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 0, 981, 981, 981, 981, 981, 981};
+
+static const flex_int16_t yy_nxt[1321] = {
+ 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 28, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 28, 53, 28, 54, 55, 56, 57, 58, 59,
+ 60, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 58, 58,
+ 58, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 58, 58, 58, 58, 63, 64, 65, 68,
+ 70, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 798, 74, 81, 86, 87, 71,
+ 69, 129, 89, 66, 74, 130, 75, 75, 75, 75, 75, 75, 75, 75, 76,
+
+ 76, 82, 77, 83, 84, 92, 103, 107, 158, 108, 104, 77, 90, 78, 799, 105, 159,
+ 127, 109, 93, 94, 106, 78, 131, 99, 79, 77, 95, 100, 96, 128, 110, 97, 98,
+ 101, 77, 132, 102, 116, 111, 78, 112, 161, 134, 113, 800, 117, 251, 252, 78, 114,
+ 135, 79, 119, 164, 165, 120, 118, 136, 121, 122, 137, 123, 139, 124, 125, 146, 126,
+ 801, 147, 140, 141, 155, 804, 142, 74, 156, 148, 164, 165, 143, 144, 150, 145, 149,
+ 157, 151, 805, 152, 200, 153, 167, 168, 154, 162, 169, 178, 77, 981, 187,
+
+ 179, 198, 201, 188, 189, 225, 806, 234, 78, 807, 210, 226, 199, 211, 212, 167, 168,
+ 213, 220, 214, 253, 77, 169, 235, 236, 981, 221, 261, 254, 262, 271, 170, 808, 170,
+ 228, 78, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 238, 229, 242, 230, 256,
+ 244, 167, 168, 286, 287, 809, 271, 257, 239, 266, 810, 266, 243, 245, 267, 267, 267,
+ 267, 267, 267, 267, 267, 267, 267, 334, 167, 168, 268, 335, 268, 411, 412, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269, 171, 171, 171, 171, 171, 171, 171,
+
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 280, 319, 320, 321,
+ 353, 361, 362, 363, 375, 376, 377, 270, 354, 281, 267, 267, 267, 267, 267, 267, 267,
+ 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 811, 270, 387, 388,
+ 389, 395, 396, 397, 399, 400, 401, 165, 269, 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 413, 414, 415, 165, 454, 455,
+ 456, 477, 478, 479, 812, 168, 490, 491, 492, 493, 494, 495, 496, 497, 498,
+
+ 598, 813, 480, 481, 542, 543, 544, 564, 573, 574, 575, 565, 814, 599, 168, 600, 618,
+ 619, 620, 815, 545, 546, 816, 817, 576, 577, 706, 802, 601, 654, 655, 656, 621, 622,
+ 818, 623, 678, 679, 680, 707, 803, 819, 708, 820, 821, 657, 658, 624, 743, 768, 822,
+ 709, 681, 682, 710, 711, 823, 744, 769, 824, 745, 770, 825, 826, 827, 828, 829, 830,
+ 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847,
+ 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862,
+
+ 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879,
+ 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896,
+ 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913,
+ 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930,
+ 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947,
+ 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962,
+
+ 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979,
+ 980, 76, 76, 797, 796, 795, 76, 88, 88, 88, 88, 88, 163, 163, 163, 163, 163,
+ 72, 794, 72, 166, 793, 166, 172, 172, 172, 792, 791, 790, 789, 788, 787, 786, 785,
+ 784, 783, 782, 781, 780, 779, 778, 777, 776, 775, 774, 773, 772, 771, 767, 766, 765,
+ 764, 763, 762, 761, 760, 759, 758, 757, 756, 755, 754, 753, 752, 751, 750, 749, 748,
+ 747, 746, 742, 741, 740, 739, 738, 737, 736, 735, 734, 733, 732, 731, 730,
+
+ 729, 728, 727, 726, 725, 724, 723, 722, 721, 720, 719, 718, 717, 716, 715, 714, 713,
+ 712, 705, 704, 703, 702, 701, 700, 699, 698, 697, 696, 695, 694, 693, 692, 691, 690,
+ 689, 688, 687, 686, 685, 684, 683, 677, 676, 675, 674, 673, 672, 671, 670, 669, 668,
+ 667, 666, 665, 664, 663, 662, 661, 660, 659, 653, 652, 651, 650, 649, 648, 647, 646,
+ 645, 644, 643, 642, 641, 640, 639, 638, 637, 636, 635, 634, 633, 632, 631, 630, 629,
+ 628, 627, 626, 625, 617, 616, 615, 614, 613, 612, 611, 610, 609, 608, 607,
+
+ 606, 605, 604, 603, 602, 597, 596, 595, 594, 593, 592, 591, 590, 589, 588, 587, 586,
+ 585, 584, 583, 582, 581, 580, 579, 578, 572, 571, 570, 569, 568, 567, 566, 563, 562,
+ 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 551, 550, 549, 548, 547, 541, 540,
+ 539, 538, 537, 536, 535, 534, 533, 532, 531, 530, 529, 528, 527, 526, 525, 524, 523,
+ 522, 521, 520, 519, 518, 517, 516, 515, 514, 513, 512, 511, 510, 509, 508, 507, 506,
+ 505, 504, 503, 502, 501, 500, 499, 489, 488, 487, 486, 485, 484, 483, 482,
+
+ 476, 475, 474, 473, 472, 471, 470, 469, 468, 467, 466, 465, 464, 463, 462, 461, 460,
+ 459, 458, 457, 453, 452, 451, 450, 449, 448, 447, 446, 445, 444, 443, 442, 441, 440,
+ 439, 438, 437, 436, 435, 434, 433, 432, 431, 430, 429, 428, 427, 426, 425, 424, 423,
+ 422, 421, 420, 419, 418, 417, 416, 410, 409, 408, 407, 406, 405, 404, 403, 402, 398,
+ 394, 393, 392, 391, 390, 386, 385, 384, 383, 382, 381, 380, 379, 378, 374, 373, 372,
+ 371, 370, 369, 368, 367, 366, 365, 364, 360, 359, 358, 357, 356, 355, 352,
+
+ 351, 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, 340, 339, 338, 337, 336, 333,
+ 332, 331, 330, 329, 328, 327, 326, 325, 324, 323, 322, 318, 317, 316, 315, 314, 313,
+ 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, 300, 299, 298, 297, 296,
+ 295, 294, 293, 292, 291, 290, 289, 288, 285, 284, 283, 282, 279, 278, 277, 276, 275,
+ 274, 273, 272, 265, 264, 263, 260, 259, 258, 255, 250, 249, 248, 247, 246, 241, 240,
+ 237, 233, 232, 231, 227, 224, 223, 222, 219, 218, 217, 216, 215, 209, 208,
+
+ 207, 206, 205, 204, 203, 202, 197, 196, 195, 194, 193, 192, 191, 190, 186, 185, 184,
+ 183, 182, 181, 180, 177, 176, 175, 174, 173, 160, 138, 133, 115, 91, 85, 80, 73,
+ 67, 62, 981, 5, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981};
+
+static const flex_int16_t yy_chk[1321] = {
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 11, 15,
+ 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 755, 21, 24, 26, 26, 17,
+ 15, 43, 31, 11, 20, 43, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+
+ 20, 24, 21, 24, 24, 33, 36, 37, 52, 37, 36, 20, 31, 21, 756, 36, 52,
+ 42, 37, 33, 33, 36, 20, 44, 35, 20, 21, 34, 35, 34, 42, 38, 34, 34,
+ 35, 20, 44, 35, 40, 38, 21, 38, 55, 46, 38, 757, 40, 150, 150, 20, 38,
+ 46, 20, 41, 72, 72, 41, 40, 46, 41, 41, 46, 41, 48, 41, 41, 49, 41,
+ 758, 49, 48, 48, 51, 760, 48, 76, 51, 49, 72, 72, 48, 48, 50, 48, 49,
+ 51, 50, 761, 50, 112, 50, 74, 74, 50, 55, 75, 94, 76, 75, 102,
+
+ 94, 111, 112, 102, 102, 132, 762, 138, 76, 763, 122, 132, 111, 122, 122, 74, 74,
+ 122, 128, 122, 151, 76, 75, 138, 138, 75, 128, 157, 151, 157, 172, 77, 764, 77,
+ 134, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 140, 134, 143, 134, 153,
+ 144, 166, 166, 189, 189, 765, 172, 153, 140, 164, 766, 164, 143, 144, 164, 164, 164,
+ 164, 164, 164, 164, 164, 164, 164, 235, 166, 166, 167, 235, 167, 314, 314, 167, 167,
+ 167, 167, 167, 167, 167, 167, 167, 167, 170, 170, 170, 170, 170, 170, 170,
+
+ 170, 170, 170, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 184, 222, 222, 222,
+ 253, 260, 260, 260, 279, 279, 279, 171, 253, 184, 266, 266, 266, 266, 266, 266, 266,
+ 266, 266, 266, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 767, 171, 291, 291,
+ 291, 300, 300, 300, 304, 304, 304, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268,
+ 268, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 315, 315, 315, 267, 359, 359,
+ 359, 403, 403, 403, 768, 269, 417, 417, 417, 418, 418, 418, 419, 419, 419,
+
+ 547, 769, 403, 403, 476, 476, 476, 507, 524, 524, 524, 507, 770, 547, 269, 548, 569,
+ 569, 569, 771, 476, 476, 772, 773, 524, 524, 665, 759, 548, 607, 607, 607, 569, 569,
+ 774, 569, 634, 634, 634, 665, 759, 775, 666, 776, 778, 607, 607, 569, 699, 724, 779,
+ 666, 634, 634, 666, 666, 780, 699, 724, 781, 699, 724, 782, 783, 784, 785, 786, 787,
+ 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804,
+ 805, 806, 807, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 821, 822,
+
+ 824, 826, 827, 828, 829, 830, 831, 832, 833, 834, 836, 837, 838, 839, 840, 841, 842,
+ 845, 846, 847, 848, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863,
+ 865, 866, 867, 868, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883,
+ 884, 885, 886, 887, 888, 891, 892, 893, 895, 896, 897, 900, 901, 902, 904, 906, 907,
+ 908, 910, 911, 912, 913, 915, 918, 919, 920, 921, 922, 923, 925, 926, 927, 928, 929,
+ 931, 932, 933, 934, 935, 937, 938, 939, 940, 941, 942, 945, 946, 947, 948,
+
+ 949, 951, 956, 960, 961, 962, 963, 965, 966, 967, 969, 970, 973, 974, 975, 976, 978,
+ 979, 982, 982, 754, 753, 752, 982, 983, 983, 983, 983, 983, 984, 984, 984, 984, 984,
+ 985, 751, 985, 986, 750, 986, 987, 987, 987, 749, 748, 747, 746, 745, 744, 743, 742,
+ 741, 740, 738, 737, 736, 735, 734, 733, 732, 731, 729, 728, 727, 726, 723, 722, 721,
+ 720, 719, 718, 716, 715, 714, 713, 712, 711, 710, 709, 708, 707, 706, 705, 704, 703,
+ 702, 701, 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, 688, 687, 686,
+
+ 685, 684, 682, 681, 680, 679, 678, 677, 676, 675, 674, 673, 672, 671, 670, 669, 668,
+ 667, 663, 661, 659, 658, 657, 656, 655, 654, 653, 650, 649, 648, 647, 646, 645, 644,
+ 643, 642, 641, 639, 638, 637, 636, 633, 631, 630, 628, 627, 625, 624, 623, 622, 621,
+ 620, 619, 618, 614, 613, 612, 611, 609, 608, 606, 605, 604, 603, 602, 601, 600, 599,
+ 598, 597, 596, 594, 593, 588, 587, 586, 585, 584, 583, 581, 580, 579, 577, 576, 575,
+ 574, 573, 571, 570, 568, 567, 566, 565, 563, 562, 561, 560, 559, 556, 555,
+
+ 554, 553, 552, 551, 550, 546, 545, 544, 543, 542, 541, 538, 537, 536, 535, 534, 533,
+ 532, 531, 530, 529, 528, 527, 526, 525, 523, 522, 519, 513, 511, 510, 509, 506, 505,
+ 502, 501, 500, 499, 488, 487, 486, 485, 484, 483, 481, 480, 479, 478, 477, 474, 472,
+ 471, 470, 468, 467, 465, 464, 462, 461, 460, 458, 457, 452, 451, 450, 448, 447, 446,
+ 445, 444, 443, 442, 441, 440, 439, 438, 436, 435, 434, 433, 432, 431, 430, 429, 428,
+ 426, 425, 424, 423, 422, 421, 420, 416, 412, 411, 410, 409, 408, 407, 404,
+
+ 402, 392, 390, 386, 385, 384, 383, 381, 380, 378, 374, 372, 371, 370, 369, 368, 367,
+ 366, 365, 360, 358, 357, 356, 355, 354, 353, 351, 350, 347, 346, 345, 344, 343, 342,
+ 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325,
+ 324, 323, 322, 321, 320, 319, 316, 313, 312, 311, 310, 309, 308, 307, 306, 305, 303,
+ 299, 297, 296, 295, 294, 290, 289, 288, 287, 286, 285, 284, 283, 282, 278, 277, 275,
+ 274, 273, 272, 265, 264, 263, 262, 261, 259, 258, 257, 256, 255, 254, 252,
+
+ 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 234,
+ 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 221, 220, 219, 218, 217, 216,
+ 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 201, 200, 199, 198,
+ 197, 196, 195, 194, 193, 192, 191, 190, 188, 187, 186, 185, 183, 182, 181, 180, 179,
+ 178, 176, 175, 160, 159, 158, 156, 155, 154, 152, 149, 148, 147, 146, 145, 142, 141,
+ 139, 137, 136, 135, 133, 131, 130, 129, 127, 126, 125, 124, 123, 121, 120,
+
+ 118, 117, 116, 115, 114, 113, 110, 109, 108, 107, 106, 105, 104, 103, 101, 100, 99,
+ 98, 97, 96, 95, 93, 92, 91, 87, 83, 53, 47, 45, 39, 32, 25, 22, 19,
+ 14, 9, 5, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981};
+
+/* Table of booleans, true if rule could match eol. */
+static const flex_int32_t yy_rule_can_match_eol[260] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+};
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+/*
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+This file contains the Lex specification for GLSL ES.
+Based on ANSI C grammar, Lex specification:
+http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
+
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN scripts/run_code_generation.py
+WHICH GENERATES THE GLSL ES LEXER (glslang_lex_autogen.cpp).
+*/
+
+#include "compiler/preprocessor/Token.h"
+#include "compiler/translator/ParseContext.h"
+#include "compiler/translator/glslang.h"
+#include "compiler/translator/length_limits.h"
+#include "compiler/translator/util.h"
+
+using namespace sh;
+
+#include "glslang_tab_autogen.h"
+
+/* windows only pragma */
+#ifdef _MSC_VER
+# pragma warning(disable : 4102)
+#endif
+
+// Workaround for flex using the register keyword, deprecated in C++11.
+#ifdef __cplusplus
+# if __cplusplus > 199711L
+# define register
+# endif
+#endif
+
+#define YY_NO_INPUT
+#define YY_USER_ACTION \
+ yylloc->first_file = yylloc->last_file = yycolumn; \
+ yylloc->first_line = yylloc->last_line = yylineno;
+
+#define YY_INPUT(buf, result, max_size) result = string_input(buf, max_size, yyscanner);
+
+static yy_size_t string_input(char *buf, yy_size_t max_size, yyscan_t yyscanner);
+static int check_type(yyscan_t yyscanner);
+static int reserved_word(yyscan_t yyscanner);
+// Tests if an extension is enabled. If the extension is promoted to core, this function returns
+// true.
+static bool is_extension_enabled_or_is_core(TParseContext *context,
+ int extension_version,
+ TExtension extension,
+ int promotion_version);
+// Helpers to determine if a symbol is reserved, keyword in extension or core, or identifier.
+// Formatted as:
+//
+// [V1_reserved_][V2_extension_][V3_keyword]
+//
+// which means in version V1, the symbol is reserved, and remains reserved until V3. From versions
+// V2 until V3, it's a keyword if the extension is enabled. From version V3 on, it's a keyword in
+// the spec itself. Prior to V1, the symbol can be used as identifier.
+static int ES2_extensions_ES3_keyword(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ TExtension extension3,
+ int token);
+static int ES2_reserved_ES3_keyword(TParseContext *context, int token);
+static int ES2_keyword_ES3_reserved(TParseContext *context, int token);
+static int ES3_keyword(TParseContext *context, int token);
+static int ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
+static int ES2_reserved_ES3_1_keyword(TParseContext *context, int token);
+static int ES3_1_keyword(TParseContext *context, int token);
+static int ES2_reserved_ES2_extension_ES3_keyword(TParseContext *context,
+ TExtension extension,
+ int token);
+static int ES3_extension(TParseContext *context, TExtension extension, int token);
+static int ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token);
+static int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token);
+static int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context,
+ TExtension extension,
+ int token);
+static int ES3_reserved_ES3_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token);
+static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token);
+static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ int token1,
+ int token2);
+static int ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ int token1,
+ int token2);
+static int WEBGL_video_texture_extension(TParseContext *context, int token);
+static int uint_constant(TParseContext *context);
+static int int_constant(TParseContext *context);
+static int float_constant(yyscan_t yyscanner);
+static int floatsuffix_check(TParseContext *context);
+static int yuvcscstandardext_constant(TParseContext *context);
+
+#define INITIAL 0
+#define FIELDS 1
+
+#define YY_EXTRA_TYPE TParseContext *
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+{
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE *yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char *yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+
+ YYSTYPE *yylval_r;
+
+ YYLTYPE *yylloc_r;
+
+}; /* end struct yyguts_t */
+
+static int yy_init_globals(yyscan_t yyscanner);
+
+/* This must go here because YYSTYPE and YYLTYPE are included
+ * from bison output in section 1.*/
+#define yylval yyg->yylval_r
+
+#define yylloc yyg->yylloc_r
+
+int yylex_init(yyscan_t *scanner);
+
+int yylex_init_extra(YY_EXTRA_TYPE user_defined, yyscan_t *scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy(yyscan_t yyscanner);
+
+int yyget_debug(yyscan_t yyscanner);
+
+void yyset_debug(int debug_flag, yyscan_t yyscanner);
+
+YY_EXTRA_TYPE yyget_extra(yyscan_t yyscanner);
+
+void yyset_extra(YY_EXTRA_TYPE user_defined, yyscan_t yyscanner);
+
+FILE *yyget_in(yyscan_t yyscanner);
+
+void yyset_in(FILE *_in_str, yyscan_t yyscanner);
+
+FILE *yyget_out(yyscan_t yyscanner);
+
+void yyset_out(FILE *_out_str, yyscan_t yyscanner);
+
+int yyget_leng(yyscan_t yyscanner);
+
+char *yyget_text(yyscan_t yyscanner);
+
+int yyget_lineno(yyscan_t yyscanner);
+
+void yyset_lineno(int _line_number, yyscan_t yyscanner);
+
+int yyget_column(yyscan_t yyscanner);
+
+void yyset_column(int _column_no, yyscan_t yyscanner);
+
+YYSTYPE *yyget_lval(yyscan_t yyscanner);
+
+void yyset_lval(YYSTYPE *yylval_param, yyscan_t yyscanner);
+
+YYLTYPE *yyget_lloc(yyscan_t yyscanner);
+
+void yyset_lloc(YYLTYPE *yylloc_param, yyscan_t yyscanner);
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+# ifdef __cplusplus
+extern "C" int yywrap(yyscan_t yyscanner);
+# else
+extern int yywrap(yyscan_t yyscanner);
+# endif
+#endif
+
+#ifndef YY_NO_UNPUT
+
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy(char *, const char *, int, yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen(const char *, yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+# ifdef __cplusplus
+static int yyinput(yyscan_t yyscanner);
+# else
+static int input(yyscan_t yyscanner);
+# endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+# ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+# define YY_READ_BUF_SIZE 16384
+# else
+# define YY_READ_BUF_SIZE 8192
+# endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+# define ECHO \
+ do \
+ { \
+ if (fwrite(yytext, (size_t)yyleng, 1, yyout)) \
+ {} \
+ } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+# define YY_INPUT(buf, result, max_size) \
+ if (YY_CURRENT_BUFFER_LVALUE->yy_is_interactive) \
+ { \
+ int c = '*'; \
+ int n; \
+ for (n = 0; n < max_size && (c = getc(yyin)) != EOF && c != '\n'; ++n) \
+ buf[n] = (char)c; \
+ if (c == '\n') \
+ buf[n++] = (char)c; \
+ if (c == EOF && ferror(yyin)) \
+ YY_FATAL_ERROR("input in flex scanner failed"); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno = 0; \
+ while ((result = (int)fread(buf, 1, (yy_size_t)max_size, yyin)) == 0 && ferror(yyin)) \
+ { \
+ if (errno != EINTR) \
+ { \
+ YY_FATAL_ERROR("input in flex scanner failed"); \
+ break; \
+ } \
+ errno = 0; \
+ clearerr(yyin); \
+ } \
+ }
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+# define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+# define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+# define YY_FATAL_ERROR(msg) yy_fatal_error(msg, yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+# define YY_DECL_IS_OURS 1
+
+extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner);
+
+# define YY_DECL int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+# define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+# define YY_BREAK /*LINTED*/ break;
+#endif
+
+#define YY_RULE_SETUP YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ yylval = yylval_param;
+
+ yylloc = yylloc_param;
+
+ if (!yyg->yy_init)
+ {
+ yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if (!yyg->yy_start)
+ yyg->yy_start = 1; /* first start state */
+
+ if (!yyin)
+ yyin = stdin;
+
+ if (!yyout)
+ yyout = stdout;
+
+ if (!YY_CURRENT_BUFFER)
+ {
+ yyensure_buffer_stack(yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner);
+ }
+
+ yy_load_buffer_state(yyscanner);
+ }
+
+ {
+
+ TParseContext *context = yyextra;
+
+ while (/*CONSTCOND*/ 1) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+ yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if (yy_accept[yy_current_state])
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 982)
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ ++yy_cp;
+ } while (yy_current_state != 981);
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+
+ yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+ if (yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act])
+ {
+ int yyl;
+ for (yyl = 0; yyl < yyleng; ++yyl)
+ if (yytext[yyl] == '\n')
+
+ do
+ {
+ yylineno++;
+ yycolumn = 0;
+ } while (0);
+ }
+
+ do_action: /* This label is used only to access EOF actions. */
+
+ switch (yy_act)
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+ case 1:
+ YY_RULE_SETUP
+ {
+ return INVARIANT;
+ }
+ YY_BREAK
+ case 2:
+ YY_RULE_SETUP
+ {
+ return HIGH_PRECISION;
+ }
+ YY_BREAK
+ case 3:
+ YY_RULE_SETUP
+ {
+ return MEDIUM_PRECISION;
+ }
+ YY_BREAK
+ case 4:
+ YY_RULE_SETUP
+ {
+ return LOW_PRECISION;
+ }
+ YY_BREAK
+ case 5:
+ YY_RULE_SETUP
+ {
+ return PRECISION;
+ }
+ YY_BREAK
+ case 6:
+ YY_RULE_SETUP
+ {
+ return ES2_keyword_ES3_reserved(context, ATTRIBUTE);
+ }
+ YY_BREAK
+ case 7:
+ YY_RULE_SETUP
+ {
+ return CONST_QUAL;
+ }
+ YY_BREAK
+ case 8:
+ YY_RULE_SETUP
+ {
+ return UNIFORM;
+ }
+ YY_BREAK
+ case 9:
+ YY_RULE_SETUP
+ {
+ return ES3_1_keyword(context, BUFFER);
+ }
+ YY_BREAK
+ case 10:
+ YY_RULE_SETUP
+ {
+ return ES2_keyword_ES3_reserved(context, VARYING);
+ }
+ YY_BREAK
+ case 11:
+ YY_RULE_SETUP
+ {
+ return BREAK;
+ }
+ YY_BREAK
+ case 12:
+ YY_RULE_SETUP
+ {
+ return CONTINUE;
+ }
+ YY_BREAK
+ case 13:
+ YY_RULE_SETUP
+ {
+ return DO;
+ }
+ YY_BREAK
+ case 14:
+ YY_RULE_SETUP
+ {
+ return FOR;
+ }
+ YY_BREAK
+ case 15:
+ YY_RULE_SETUP
+ {
+ return WHILE;
+ }
+ YY_BREAK
+ case 16:
+ YY_RULE_SETUP
+ {
+ return IF;
+ }
+ YY_BREAK
+ case 17:
+ YY_RULE_SETUP
+ {
+ return ELSE;
+ }
+ YY_BREAK
+ case 18:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES3_keyword(context, SWITCH);
+ }
+ YY_BREAK
+ case 19:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, CASE);
+ }
+ YY_BREAK
+ case 20:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES3_keyword(context, DEFAULT);
+ }
+ YY_BREAK
+ case 21:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, CENTROID);
+ }
+ YY_BREAK
+ case 22:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES3_keyword(context, FLAT);
+ }
+ YY_BREAK
+ case 23:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, SMOOTH);
+ }
+ YY_BREAK
+ case 24:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_extension(
+ context, TExtension::NV_shader_noperspective_interpolation,
+ NOPERSPECTIVE);
+ }
+ YY_BREAK
+ case 25:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_extension_ES3_2_keyword(
+ context, TExtension::EXT_tessellation_shader, PATCH);
+ }
+ YY_BREAK
+ case 26:
+ YY_RULE_SETUP
+ {
+ return IN_QUAL;
+ }
+ YY_BREAK
+ case 27:
+ YY_RULE_SETUP
+ {
+ return OUT_QUAL;
+ }
+ YY_BREAK
+ case 28:
+ YY_RULE_SETUP
+ {
+ return INOUT_QUAL;
+ }
+ YY_BREAK
+ case 29:
+ YY_RULE_SETUP
+ {
+ return ES3_1_keyword(context, SHARED);
+ }
+ YY_BREAK
+ case 30:
+ YY_RULE_SETUP
+ {
+ return FLOAT_TYPE;
+ }
+ YY_BREAK
+ case 31:
+ YY_RULE_SETUP
+ {
+ return INT_TYPE;
+ }
+ YY_BREAK
+ case 32:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, UINT_TYPE);
+ }
+ YY_BREAK
+ case 33:
+ YY_RULE_SETUP
+ {
+ return VOID_TYPE;
+ }
+ YY_BREAK
+ case 34:
+ YY_RULE_SETUP
+ {
+ return BOOL_TYPE;
+ }
+ YY_BREAK
+ case 35:
+ YY_RULE_SETUP
+ {
+ yylval->lex.b = true;
+ return BOOLCONSTANT;
+ }
+ YY_BREAK
+ case 36:
+ YY_RULE_SETUP
+ {
+ yylval->lex.b = false;
+ return BOOLCONSTANT;
+ }
+ YY_BREAK
+ case 37:
+ YY_RULE_SETUP
+ {
+ return DISCARD;
+ }
+ YY_BREAK
+ case 38:
+ YY_RULE_SETUP
+ {
+ return RETURN;
+ }
+ YY_BREAK
+ case 39:
+ YY_RULE_SETUP
+ {
+ return MATRIX2;
+ }
+ YY_BREAK
+ case 40:
+ YY_RULE_SETUP
+ {
+ return MATRIX3;
+ }
+ YY_BREAK
+ case 41:
+ YY_RULE_SETUP
+ {
+ return MATRIX4;
+ }
+ YY_BREAK
+ case 42:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX2);
+ }
+ YY_BREAK
+ case 43:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX3);
+ }
+ YY_BREAK
+ case 44:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX4);
+ }
+ YY_BREAK
+ case 45:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX2x3);
+ }
+ YY_BREAK
+ case 46:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX3x2);
+ }
+ YY_BREAK
+ case 47:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX2x4);
+ }
+ YY_BREAK
+ case 48:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX4x2);
+ }
+ YY_BREAK
+ case 49:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX3x4);
+ }
+ YY_BREAK
+ case 50:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX4x3);
+ }
+ YY_BREAK
+ case 51:
+ YY_RULE_SETUP
+ {
+ return VEC2;
+ }
+ YY_BREAK
+ case 52:
+ YY_RULE_SETUP
+ {
+ return VEC3;
+ }
+ YY_BREAK
+ case 53:
+ YY_RULE_SETUP
+ {
+ return VEC4;
+ }
+ YY_BREAK
+ case 54:
+ YY_RULE_SETUP
+ {
+ return IVEC2;
+ }
+ YY_BREAK
+ case 55:
+ YY_RULE_SETUP
+ {
+ return IVEC3;
+ }
+ YY_BREAK
+ case 56:
+ YY_RULE_SETUP
+ {
+ return IVEC4;
+ }
+ YY_BREAK
+ case 57:
+ YY_RULE_SETUP
+ {
+ return BVEC2;
+ }
+ YY_BREAK
+ case 58:
+ YY_RULE_SETUP
+ {
+ return BVEC3;
+ }
+ YY_BREAK
+ case 59:
+ YY_RULE_SETUP
+ {
+ return BVEC4;
+ }
+ YY_BREAK
+ case 60:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, UVEC2);
+ }
+ YY_BREAK
+ case 61:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, UVEC3);
+ }
+ YY_BREAK
+ case 62:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, UVEC4);
+ }
+ YY_BREAK
+ case 63:
+ YY_RULE_SETUP
+ {
+ return SAMPLER2D;
+ }
+ YY_BREAK
+ case 64:
+ YY_RULE_SETUP
+ {
+ return SAMPLERCUBE;
+ }
+ YY_BREAK
+ case 65:
+ YY_RULE_SETUP
+ {
+ return SAMPLER_EXTERNAL_OES;
+ }
+ YY_BREAK
+ case 66:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES2_extension_ES3_keyword(
+ context, TExtension::OES_texture_3D, SAMPLER3D);
+ }
+ YY_BREAK
+ case 67:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT);
+ }
+ YY_BREAK
+ case 68:
+ YY_RULE_SETUP
+ {
+ return SAMPLER2DRECT;
+ }
+ YY_BREAK
+ case 69:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, SAMPLER2DARRAY);
+ }
+ YY_BREAK
+ case 70:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_extension_ES3_1_keyword(
+ context, TExtension::ANGLE_texture_multisample, SAMPLER2DMS);
+ }
+ YY_BREAK
+ case 71:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, ISAMPLER2D);
+ }
+ YY_BREAK
+ case 72:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, ISAMPLER3D);
+ }
+ YY_BREAK
+ case 73:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, ISAMPLERCUBE);
+ }
+ YY_BREAK
+ case 74:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, ISAMPLER2DARRAY);
+ }
+ YY_BREAK
+ case 75:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_extension_ES3_1_keyword(
+ context, TExtension::ANGLE_texture_multisample, ISAMPLER2DMS);
+ }
+ YY_BREAK
+ case 76:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, USAMPLER2D);
+ }
+ YY_BREAK
+ case 77:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, USAMPLER3D);
+ }
+ YY_BREAK
+ case 78:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, USAMPLERCUBE);
+ }
+ YY_BREAK
+ case 79:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, USAMPLER2DARRAY);
+ }
+ YY_BREAK
+ case 80:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_extension_ES3_1_keyword(
+ context, TExtension::ANGLE_texture_multisample, USAMPLER2DMS);
+ }
+ YY_BREAK
+ case 81:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES2_extension_ES3_keyword(
+ context, TExtension::EXT_shadow_samplers, SAMPLER2DSHADOW);
+ }
+ YY_BREAK
+ case 82:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, SAMPLERCUBESHADOW);
+ }
+ YY_BREAK
+ case 83:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, SAMPLER2DARRAYSHADOW);
+ }
+ YY_BREAK
+ case 84:
+ YY_RULE_SETUP
+ {
+ return ES3_extension(context, TExtension::EXT_YUV_target,
+ SAMPLEREXTERNAL2DY2YEXT);
+ }
+ YY_BREAK
+ case 85:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_extension_ES3_2_keyword(
+ context, TExtension::OES_texture_storage_multisample_2d_array,
+ SAMPLER2DMSARRAY);
+ }
+ YY_BREAK
+ case 86:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_extension_ES3_2_keyword(
+ context, TExtension::OES_texture_storage_multisample_2d_array,
+ ISAMPLER2DMSARRAY);
+ }
+ YY_BREAK
+ case 87:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_extension_ES3_2_keyword(
+ context, TExtension::OES_texture_storage_multisample_2d_array,
+ USAMPLER2DMSARRAY);
+ }
+ YY_BREAK
+ case 88:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, SAMPLERCUBEARRAYOES,
+ SAMPLERCUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 89:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ SAMPLERBUFFER, SAMPLERBUFFER);
+ }
+ YY_BREAK
+ case 90:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, SAMPLERCUBEARRAYSHADOWOES,
+ SAMPLERCUBEARRAYSHADOWEXT);
+ }
+ YY_BREAK
+ case 91:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, ISAMPLERCUBEARRAYOES,
+ ISAMPLERCUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 92:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ ISAMPLERBUFFER, ISAMPLERBUFFER);
+ }
+ YY_BREAK
+ case 93:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, USAMPLERCUBEARRAYOES,
+ USAMPLERCUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 94:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ USAMPLERBUFFER, USAMPLERBUFFER);
+ }
+ YY_BREAK
+ case 95:
+ YY_RULE_SETUP
+ {
+ return WEBGL_video_texture_extension(context, SAMPLERVIDEOWEBGL);
+ }
+ YY_BREAK
+ case 96:
+ YY_RULE_SETUP
+ {
+ return STRUCT;
+ }
+ YY_BREAK
+ case 97:
+ YY_RULE_SETUP
+ {
+ return ES2_extensions_ES3_keyword(
+ context, TExtension::EXT_shader_framebuffer_fetch,
+ TExtension::EXT_shader_framebuffer_fetch_non_coherent,
+ TExtension::KHR_blend_equation_advanced, LAYOUT);
+ }
+ YY_BREAK
+ case 98:
+ YY_RULE_SETUP
+ {
+ return ES3_extension(context, TExtension::EXT_YUV_target,
+ YUVCSCSTANDARDEXT);
+ }
+ YY_BREAK
+ case 99:
+ YY_RULE_SETUP
+ {
+ return yuvcscstandardext_constant(context);
+ }
+ YY_BREAK
+ case 100:
+ YY_RULE_SETUP
+ {
+ return yuvcscstandardext_constant(context);
+ }
+ YY_BREAK
+ case 101:
+ YY_RULE_SETUP
+ {
+ return yuvcscstandardext_constant(context);
+ }
+ YY_BREAK
+ case 102:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IMAGE2D);
+ }
+ YY_BREAK
+ case 103:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IIMAGE2D);
+ }
+ YY_BREAK
+ case 104:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, UIMAGE2D);
+ }
+ YY_BREAK
+ case 105:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IMAGE2DARRAY);
+ }
+ YY_BREAK
+ case 106:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IIMAGE2DARRAY);
+ }
+ YY_BREAK
+ case 107:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, UIMAGE2DARRAY);
+ }
+ YY_BREAK
+ case 108:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IMAGE3D);
+ }
+ YY_BREAK
+ case 109:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, UIMAGE3D);
+ }
+ YY_BREAK
+ case 110:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IIMAGE3D);
+ }
+ YY_BREAK
+ case 111:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IIMAGECUBE);
+ }
+ YY_BREAK
+ case 112:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, UIMAGECUBE);
+ }
+ YY_BREAK
+ case 113:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IMAGECUBE);
+ }
+ YY_BREAK
+ case 114:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, IMAGECUBEARRAYOES,
+ IMAGECUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 115:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, IIMAGECUBEARRAYOES,
+ IIMAGECUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 116:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, UIMAGECUBEARRAYOES,
+ UIMAGECUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 117:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ IMAGEBUFFER, IMAGEBUFFER);
+ }
+ YY_BREAK
+ case 118:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ IIMAGEBUFFER, IIMAGEBUFFER);
+ }
+ YY_BREAK
+ case 119:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ UIMAGEBUFFER, UIMAGEBUFFER);
+ }
+ YY_BREAK
+ case 120:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, READONLY);
+ }
+ YY_BREAK
+ case 121:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, WRITEONLY);
+ }
+ YY_BREAK
+ case 122:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, COHERENT);
+ }
+ YY_BREAK
+ case 123:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, RESTRICT);
+ }
+ YY_BREAK
+ case 124:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES3_1_keyword(context, VOLATILE);
+ }
+ YY_BREAK
+ case 125:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, ATOMICUINT);
+ }
+ YY_BREAK
+ case 126:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_extension_ES3_2_keyword(
+ context, TExtension::OES_shader_multisample_interpolation, SAMPLE);
+ }
+ YY_BREAK
+ case 127:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword(
+ context, TExtension::EXT_gpu_shader5, PRECISE);
+ }
+ YY_BREAK
+ /* ANGLE_shader_pixel_local_storage */
+ case 128:
+ YY_RULE_SETUP
+ {
+ return ES3_extension(context, TExtension::ANGLE_shader_pixel_local_storage,
+ PIXELLOCALANGLE);
+ }
+ YY_BREAK
+ case 129:
+ YY_RULE_SETUP
+ {
+ return ES3_extension(context, TExtension::ANGLE_shader_pixel_local_storage,
+ IPIXELLOCALANGLE);
+ }
+ YY_BREAK
+ case 130:
+ YY_RULE_SETUP
+ {
+ return ES3_extension(context, TExtension::ANGLE_shader_pixel_local_storage,
+ UPIXELLOCALANGLE);
+ }
+ YY_BREAK
+ /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */
+ case 131:
+ case 132:
+ case 133:
+ case 134:
+ case 135:
+ case 136:
+ case 137:
+ case 138:
+ case 139:
+ case 140:
+ case 141:
+ case 142:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ case 147:
+ case 148:
+ case 149:
+ case 150:
+ case 151:
+ case 152:
+ case 153:
+ case 154:
+ YY_RULE_SETUP
+ {
+ if (context->getShaderVersion() < 300)
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+ return reserved_word(yyscanner);
+ }
+ YY_BREAK
+ /* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */
+ case 155:
+ YY_RULE_SETUP
+ {
+ if (context->getShaderVersion() >= 300)
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+
+ return reserved_word(yyscanner);
+ }
+ YY_BREAK
+ /* Reserved keywords */
+ case 156:
+ case 157:
+ case 158:
+ case 159:
+ case 160:
+ case 161:
+ case 162:
+ case 163:
+ case 164:
+ case 165:
+ case 166:
+ case 167:
+ case 168:
+ case 169:
+ case 170:
+ case 171:
+ case 172:
+ case 173:
+ case 174:
+ case 175:
+ case 176:
+ case 177:
+ case 178:
+ case 179:
+ case 180:
+ case 181:
+ case 182:
+ case 183:
+ case 184:
+ case 185:
+ case 186:
+ case 187:
+ case 188:
+ case 189:
+ case 190:
+ case 191:
+ case 192:
+ case 193:
+ case 194:
+ case 195:
+ YY_RULE_SETUP
+ {
+ return reserved_word(yyscanner);
+ }
+ YY_BREAK
+ case 196:
+ YY_RULE_SETUP
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+ YY_BREAK
+ case 197:
+ YY_RULE_SETUP
+ {
+ return int_constant(context);
+ }
+ YY_BREAK
+ case 198:
+ YY_RULE_SETUP
+ {
+ return int_constant(context);
+ }
+ YY_BREAK
+ case 199:
+ YY_RULE_SETUP
+ {
+ return int_constant(context);
+ }
+ YY_BREAK
+ case 200:
+ YY_RULE_SETUP
+ {
+ return uint_constant(context);
+ }
+ YY_BREAK
+ case 201:
+ YY_RULE_SETUP
+ {
+ return uint_constant(context);
+ }
+ YY_BREAK
+ case 202:
+ YY_RULE_SETUP
+ {
+ return uint_constant(context);
+ }
+ YY_BREAK
+ case 203:
+ YY_RULE_SETUP
+ {
+ return float_constant(yyscanner);
+ }
+ YY_BREAK
+ case 204:
+ YY_RULE_SETUP
+ {
+ return float_constant(yyscanner);
+ }
+ YY_BREAK
+ case 205:
+ YY_RULE_SETUP
+ {
+ return float_constant(yyscanner);
+ }
+ YY_BREAK
+ case 206:
+ YY_RULE_SETUP
+ {
+ return floatsuffix_check(context);
+ }
+ YY_BREAK
+ case 207:
+ YY_RULE_SETUP
+ {
+ return floatsuffix_check(context);
+ }
+ YY_BREAK
+ case 208:
+ YY_RULE_SETUP
+ {
+ return floatsuffix_check(context);
+ }
+ YY_BREAK
+ case 209:
+ YY_RULE_SETUP
+ {
+ return ADD_ASSIGN;
+ }
+ YY_BREAK
+ case 210:
+ YY_RULE_SETUP
+ {
+ return SUB_ASSIGN;
+ }
+ YY_BREAK
+ case 211:
+ YY_RULE_SETUP
+ {
+ return MUL_ASSIGN;
+ }
+ YY_BREAK
+ case 212:
+ YY_RULE_SETUP
+ {
+ return DIV_ASSIGN;
+ }
+ YY_BREAK
+ case 213:
+ YY_RULE_SETUP
+ {
+ return MOD_ASSIGN;
+ }
+ YY_BREAK
+ case 214:
+ YY_RULE_SETUP
+ {
+ return LEFT_ASSIGN;
+ }
+ YY_BREAK
+ case 215:
+ YY_RULE_SETUP
+ {
+ return RIGHT_ASSIGN;
+ }
+ YY_BREAK
+ case 216:
+ YY_RULE_SETUP
+ {
+ return AND_ASSIGN;
+ }
+ YY_BREAK
+ case 217:
+ YY_RULE_SETUP
+ {
+ return XOR_ASSIGN;
+ }
+ YY_BREAK
+ case 218:
+ YY_RULE_SETUP
+ {
+ return OR_ASSIGN;
+ }
+ YY_BREAK
+ case 219:
+ YY_RULE_SETUP
+ {
+ return INC_OP;
+ }
+ YY_BREAK
+ case 220:
+ YY_RULE_SETUP
+ {
+ return DEC_OP;
+ }
+ YY_BREAK
+ case 221:
+ YY_RULE_SETUP
+ {
+ return AND_OP;
+ }
+ YY_BREAK
+ case 222:
+ YY_RULE_SETUP
+ {
+ return OR_OP;
+ }
+ YY_BREAK
+ case 223:
+ YY_RULE_SETUP
+ {
+ return XOR_OP;
+ }
+ YY_BREAK
+ case 224:
+ YY_RULE_SETUP
+ {
+ return LE_OP;
+ }
+ YY_BREAK
+ case 225:
+ YY_RULE_SETUP
+ {
+ return GE_OP;
+ }
+ YY_BREAK
+ case 226:
+ YY_RULE_SETUP
+ {
+ return EQ_OP;
+ }
+ YY_BREAK
+ case 227:
+ YY_RULE_SETUP
+ {
+ return NE_OP;
+ }
+ YY_BREAK
+ case 228:
+ YY_RULE_SETUP
+ {
+ return LEFT_OP;
+ }
+ YY_BREAK
+ case 229:
+ YY_RULE_SETUP
+ {
+ return RIGHT_OP;
+ }
+ YY_BREAK
+ case 230:
+ YY_RULE_SETUP
+ {
+ return SEMICOLON;
+ }
+ YY_BREAK
+ case 231:
+ YY_RULE_SETUP
+ {
+ return LEFT_BRACE;
+ }
+ YY_BREAK
+ case 232:
+ YY_RULE_SETUP
+ {
+ return RIGHT_BRACE;
+ }
+ YY_BREAK
+ case 233:
+ YY_RULE_SETUP
+ {
+ return COMMA;
+ }
+ YY_BREAK
+ case 234:
+ YY_RULE_SETUP
+ {
+ return COLON;
+ }
+ YY_BREAK
+ case 235:
+ YY_RULE_SETUP
+ {
+ return EQUAL;
+ }
+ YY_BREAK
+ case 236:
+ YY_RULE_SETUP
+ {
+ return LEFT_PAREN;
+ }
+ YY_BREAK
+ case 237:
+ YY_RULE_SETUP
+ {
+ return RIGHT_PAREN;
+ }
+ YY_BREAK
+ case 238:
+ YY_RULE_SETUP
+ {
+ return LEFT_BRACKET;
+ }
+ YY_BREAK
+ case 239:
+ YY_RULE_SETUP
+ {
+ return RIGHT_BRACKET;
+ }
+ YY_BREAK
+ case 240:
+ YY_RULE_SETUP
+ {
+ BEGIN(FIELDS);
+ return DOT;
+ }
+ YY_BREAK
+ case 241:
+ YY_RULE_SETUP
+ {
+ return BANG;
+ }
+ YY_BREAK
+ case 242:
+ YY_RULE_SETUP
+ {
+ return DASH;
+ }
+ YY_BREAK
+ case 243:
+ YY_RULE_SETUP
+ {
+ return TILDE;
+ }
+ YY_BREAK
+ case 244:
+ YY_RULE_SETUP
+ {
+ return PLUS;
+ }
+ YY_BREAK
+ case 245:
+ YY_RULE_SETUP
+ {
+ return STAR;
+ }
+ YY_BREAK
+ case 246:
+ YY_RULE_SETUP
+ {
+ return SLASH;
+ }
+ YY_BREAK
+ case 247:
+ YY_RULE_SETUP
+ {
+ return PERCENT;
+ }
+ YY_BREAK
+ case 248:
+ YY_RULE_SETUP
+ {
+ return LEFT_ANGLE;
+ }
+ YY_BREAK
+ case 249:
+ YY_RULE_SETUP
+ {
+ return RIGHT_ANGLE;
+ }
+ YY_BREAK
+ case 250:
+ YY_RULE_SETUP
+ {
+ return VERTICAL_BAR;
+ }
+ YY_BREAK
+ case 251:
+ YY_RULE_SETUP
+ {
+ return CARET;
+ }
+ YY_BREAK
+ case 252:
+ YY_RULE_SETUP
+ {
+ return AMPERSAND;
+ }
+ YY_BREAK
+ case 253:
+ YY_RULE_SETUP
+ {
+ return QUESTION;
+ }
+ YY_BREAK
+ case 254:
+ YY_RULE_SETUP
+ {
+ BEGIN(INITIAL);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return FIELD_SELECTION;
+ }
+ YY_BREAK
+ case 255:
+ YY_RULE_SETUP {}
+ YY_BREAK
+ case 256:
+ YY_RULE_SETUP
+ {
+ yyextra->error(*yylloc, "Illegal character at fieldname start", yytext);
+ return 0;
+ }
+ YY_BREAK
+ case 257:
+ /* rule 257 can match eol */
+ YY_RULE_SETUP {}
+ YY_BREAK
+ case YY_STATE_EOF(INITIAL):
+ case YY_STATE_EOF(FIELDS):
+ {
+ yyterminate();
+ }
+ YY_BREAK
+ case 258:
+ YY_RULE_SETUP
+ {
+ assert(false);
+ return 0;
+ }
+ YY_BREAK
+ case 259:
+ YY_RULE_SETUP
+ ECHO;
+ YY_BREAK
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int)(yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if (YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW)
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if (yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars])
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state(yyscanner);
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans(yy_current_state, yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if (yy_next_state)
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+ }
+ }
+
+ else
+ switch (yy_get_next_buffer(yyscanner))
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if (yywrap(yyscanner))
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if (!yyg->yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state(yyscanner);
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state(yyscanner);
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR("fatal flex scanner internal error--no action found");
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = yyg->yytext_ptr;
+ int number_to_move, i;
+ int ret_val;
+
+ if (yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1])
+ YY_FATAL_ERROR("fatal flex scanner internal error--end of buffer missed");
+
+ if (YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0)
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if (yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1)
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int)(yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
+
+ for (i = 0; i < number_to_move; ++i)
+ *(dest++) = *(source++);
+
+ if (YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING)
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while (num_to_read <= 0)
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset = (int)(yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if (b->yy_is_our_buffer)
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if (new_size <= 0)
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *)b->yy_ch_buf, (yy_size_t)(b->yy_buf_size + 2), yyscanner);
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = NULL;
+
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR("fatal error - scanner input buffer overflow");
+
+ yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+ }
+
+ if (num_to_read > YY_READ_BUF_SIZE)
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ yy_size_t ret = 0;
+ YY_INPUT((&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), ret, num_to_read);
+ yyg->yy_n_chars = static_cast<int>(ret);
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if (yyg->yy_n_chars == 0)
+ {
+ if (number_to_move == YY_MORE_ADJ)
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin, yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size)
+ {
+ /* Extend the array by 50%, plus the number we really need. */
+ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *)yyrealloc(
+ (void *)YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t)new_size, yyscanner);
+ if (!YY_CURRENT_BUFFER_LVALUE->yy_ch_buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_get_next_buffer()");
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int)(new_size - 2);
+ }
+
+ yyg->yy_n_chars += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state(yyscan_t yyscanner)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for (yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp)
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if (yy_accept[yy_current_state])
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 982)
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state, yyscan_t yyscanner)
+{
+ int yy_is_jam;
+ struct yyguts_t *yyg =
+ (struct yyguts_t *)yyscanner; /* This var may be unused depending upon options. */
+ char *yy_cp = yyg->yy_c_buf_p;
+
+ YY_CHAR yy_c = 1;
+ if (yy_accept[yy_current_state])
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 982)
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 981);
+
+ (void)yyg;
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+
+#endif
+
+#ifndef YY_NO_INPUT
+# ifdef __cplusplus
+static int yyinput(yyscan_t yyscanner)
+# else
+static int input(yyscan_t yyscanner)
+# endif
+
+{
+ int c;
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if (*yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR)
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if (yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars])
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = (int)(yyg->yy_c_buf_p - yyg->yytext_ptr);
+ ++yyg->yy_c_buf_p;
+
+ switch (yy_get_next_buffer(yyscanner))
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin, yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if (yywrap(yyscanner))
+ return 0;
+
+ if (!yyg->yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+# ifdef __cplusplus
+ return yyinput(yyscanner);
+# else
+ return input(yyscanner);
+# endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *)yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ if (c == '\n')
+
+ do
+ {
+ yylineno++;
+ yycolumn = 0;
+ } while (0);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+void yyrestart(FILE *input_file, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!YY_CURRENT_BUFFER)
+ {
+ yyensure_buffer_stack(yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner);
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER, input_file, yyscanner);
+ yy_load_buffer_state(yyscanner);
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack(yyscanner);
+ if (YY_CURRENT_BUFFER == new_buffer)
+ return;
+
+ if (YY_CURRENT_BUFFER)
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state(yyscanner);
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void yy_load_buffer_state(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+YY_BUFFER_STATE yy_create_buffer(FILE *file, int size, yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE)yyalloc(sizeof(struct yy_buffer_state), yyscanner);
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *)yyalloc((yy_size_t)(b->yy_buf_size + 2), yyscanner);
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b, file, yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+void yy_delete_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!b)
+ return;
+
+ if (b == YY_CURRENT_BUFFER) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE)0;
+
+ if (b->yy_is_our_buffer)
+ yyfree((void *)b->yy_ch_buf, yyscanner);
+
+ yyfree((void *)b, yyscanner);
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+static void yy_init_buffer(YY_BUFFER_STATE b, FILE *file, yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ yy_flush_buffer(b, yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER)
+ {
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+void yy_flush_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ if (!b)
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if (b == YY_CURRENT_BUFFER)
+ yy_load_buffer_state(yyscanner);
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void yypush_buffer_state(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if (YY_CURRENT_BUFFER)
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state(yyscanner);
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * @param yyscanner The scanner object.
+ */
+void yypop_buffer_state(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER)
+ {
+ yy_load_buffer_state(yyscanner);
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack(yyscan_t yyscanner)
+{
+ yy_size_t num_to_alloc;
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!yyg->yy_buffer_stack)
+ {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ yyg->yy_buffer_stack = (struct yy_buffer_state **)yyalloc(
+ num_to_alloc * sizeof(struct yy_buffer_state *), yyscanner);
+ if (!yyg->yy_buffer_stack)
+ YY_FATAL_ERROR("out of dynamic memory in yyensure_buffer_stack()");
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state *));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1)
+ {
+
+ /* Increase the buffer to prepare for a possible push. */
+ yy_size_t grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state **)yyrealloc(
+ yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state *), yyscanner);
+ if (!yyg->yy_buffer_stack)
+ YY_FATAL_ERROR("out of dynamic memory in yyensure_buffer_stack()");
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0,
+ grow_size * sizeof(struct yy_buffer_state *));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size, yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if (size < 2 || base[size - 2] != YY_END_OF_BUFFER_CHAR ||
+ base[size - 1] != YY_END_OF_BUFFER_CHAR)
+ /* They forgot to leave room for the EOB's. */
+ return NULL;
+
+ b = (YY_BUFFER_STATE)yyalloc(sizeof(struct yy_buffer_state), yyscanner);
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_buffer()");
+
+ b->yy_buf_size = (int)(size - 2); /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = NULL;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b, yyscanner);
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string(const char *yystr, yyscan_t yyscanner)
+{
+
+ return yy_scan_bytes(yystr, (int)strlen(yystr), yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes(const char *yybytes, int _yybytes_len, yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = (yy_size_t)(_yybytes_len + 2);
+ buf = (char *)yyalloc(n, yyscanner);
+ if (!buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_bytes()");
+
+ for (i = 0; i < _yybytes_len; ++i)
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len + 1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf, n, yyscanner);
+ if (!b)
+ YY_FATAL_ERROR("bad buffer in yy_scan_bytes()");
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+# define YY_EXIT_FAILURE 2
+#endif
+
+static void yynoreturn yy_fatal_error(const char *msg, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ (void)yyg;
+ fprintf(stderr, "%s\n", msg);
+ exit(YY_EXIT_FAILURE);
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg); \
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } while (0)
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE yyget_extra(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_lineno(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!YY_CURRENT_BUFFER)
+ return 0;
+
+ return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_column(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!YY_CURRENT_BUFFER)
+ return 0;
+
+ return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_in(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_out(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int yyget_leng(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *yyget_text(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void yyset_extra(YY_EXTRA_TYPE user_defined, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyextra = user_defined;
+}
+
+/** Set the current line number.
+ * @param _line_number line number
+ * @param yyscanner The scanner object.
+ */
+void yyset_lineno(int _line_number, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ /* lineno is only valid if an input buffer exists. */
+ if (!YY_CURRENT_BUFFER)
+ YY_FATAL_ERROR("yyset_lineno called with no buffer");
+
+ yylineno = _line_number;
+}
+
+/** Set the current column.
+ * @param _column_no column number
+ * @param yyscanner The scanner object.
+ */
+void yyset_column(int _column_no, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ /* column is only valid if an input buffer exists. */
+ if (!YY_CURRENT_BUFFER)
+ YY_FATAL_ERROR("yyset_column called with no buffer");
+
+ yycolumn = _column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see yy_switch_to_buffer
+ */
+void yyset_in(FILE *_in_str, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyin = _in_str;
+}
+
+void yyset_out(FILE *_out_str, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyout = _out_str;
+}
+
+int yyget_debug(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yy_flex_debug;
+}
+
+void yyset_debug(int _bdebug, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yy_flex_debug = _bdebug;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE *yyget_lval(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yylval;
+}
+
+void yyset_lval(YYSTYPE *yylval_param, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yylval = yylval_param;
+}
+
+YYLTYPE *yyget_lloc(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yylloc;
+}
+
+void yyset_lloc(YYLTYPE *yylloc_param, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yylloc = yylloc_param;
+}
+
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+int yylex_init(yyscan_t *ptr_yy_globals)
+{
+ if (ptr_yy_globals == NULL)
+ {
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t)yyalloc(sizeof(struct yyguts_t), NULL);
+
+ if (*ptr_yy_globals == NULL)
+ {
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals, 0x00, sizeof(struct yyguts_t));
+
+ return yy_init_globals(*ptr_yy_globals);
+}
+
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to yyalloc in
+ * the yyextra field.
+ */
+int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined, yyscan_t *ptr_yy_globals)
+{
+ struct yyguts_t dummy_yyguts;
+
+ yyset_extra(yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL)
+ {
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t)yyalloc(sizeof(struct yyguts_t), &dummy_yyguts);
+
+ if (*ptr_yy_globals == NULL)
+ {
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals, 0x00, sizeof(struct yyguts_t));
+
+ yyset_extra(yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals(*ptr_yy_globals);
+}
+
+static int yy_init_globals(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = NULL;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 0;
+ yyg->yy_c_buf_p = NULL;
+ yyg->yy_init = 0;
+ yyg->yy_start = 0;
+
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = NULL;
+ yyout = NULL;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while (YY_CURRENT_BUFFER)
+ {
+ yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ yyfree(yyg->yy_buffer_stack, yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ yyfree(yyg->yy_start_stack, yyscanner);
+ yyg->yy_start_stack = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals(yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ yyfree(yyscanner, yyscanner);
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy(char *s1, const char *s2, int n, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ (void)yyg;
+
+ int i;
+ for (i = 0; i < n; ++i)
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen(const char *s, yyscan_t yyscanner)
+{
+ int n;
+ for (n = 0; s[n]; ++n)
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc(yy_size_t size, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ (void)yyg;
+ return malloc(size);
+}
+
+void *yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ (void)yyg;
+
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return realloc(ptr, size);
+}
+
+void yyfree(void *ptr, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ (void)yyg;
+ free((char *)ptr); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+yy_size_t string_input(char *buf, yy_size_t max_size, yyscan_t yyscanner)
+{
+ angle::pp::Token token;
+ yyget_extra(yyscanner)->getPreprocessor().lex(&token);
+ yy_size_t len = token.type == angle::pp::Token::LAST ? 0 : token.text.size();
+ if (len < max_size)
+ memcpy(buf, token.text.c_str(), len);
+ yyset_column(token.location.file, yyscanner);
+ yyset_lineno(token.location.line, yyscanner);
+
+ if (len >= max_size)
+ YY_FATAL_ERROR("Input buffer overflow");
+ else if (len > 0)
+ buf[len++] = ' ';
+ return len;
+}
+
+int check_type(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ int token = IDENTIFIER;
+ // Note that the ImmutableString used here isn't static or pool allocated - but it's fine since
+ // yytext is valid for the duration of its use.
+ const TSymbol *symbol =
+ yyextra->symbolTable.find(ImmutableString(yytext, yyleng), yyextra->getShaderVersion());
+ if (symbol && symbol->isStruct())
+ {
+ token = TYPE_NAME;
+ }
+ yylval->lex.symbol = symbol;
+ return token;
+}
+
+int reserved_word(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ yyextra->error(*yylloc, "Illegal use of reserved word", yytext);
+ return 0;
+}
+
+static bool is_extension_enabled_or_is_core(TParseContext *context,
+ int extension_version,
+ TExtension extension,
+ int promotion_version)
+{
+ int version = context->getShaderVersion();
+
+ // If version is at least promotion_version, symbol is definitely keyword. Otherwise it's a
+ // keyword if version is at least extension_version (where the extension was introduced) and
+ // the extension is enabled.
+ return version >= promotion_version ||
+ (version >= extension_version && context->isExtensionEnabled(extension));
+}
+
+int ES2_reserved_ES3_keyword(TParseContext *context, int token)
+{
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ if (context->getShaderVersion() < 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ return token;
+}
+
+int ES2_keyword_ES3_reserved(TParseContext *context, int token)
+{
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ if (context->getShaderVersion() >= 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ return token;
+}
+
+int ES3_reserved_ES3_1_keyword(TParseContext *context, int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ if (context->getShaderVersion() < 300)
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+ else if (context->getShaderVersion() == 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ return token;
+}
+
+int ES3_keyword(TParseContext *context, int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
+ if (context->getShaderVersion() < 300)
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+
+ return token;
+}
+
+int ES2_reserved_ES3_1_keyword(TParseContext *context, int token)
+{
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ if (context->getShaderVersion() < 310)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ return token;
+}
+
+int ES3_1_keyword(TParseContext *context, int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.10.
+ if (context->getShaderVersion() >= 310)
+ {
+ return token;
+ }
+
+ // Otherwise can be used as an identifier/type name
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int WEBGL_video_texture_extension(TParseContext *context, int token)
+{
+ // Available with WEBGL_video_texture_extension
+ if (context->isExtensionEnabled(TExtension::WEBGL_video_texture))
+ {
+ return token;
+ }
+
+ // Otherwise can be used as an identifier/type name
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES2_extensions_ES3_keyword(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ TExtension extension3,
+ int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.00 or GLSL ES 1.00 with enabled extension.
+ if (is_extension_enabled_or_is_core(context, 100, extension1, 300))
+ {
+ return token;
+ }
+ else if (is_extension_enabled_or_is_core(context, 100, extension2, 300))
+ {
+ return token;
+ }
+ else if (is_extension_enabled_or_is_core(context, 100, extension3, 300))
+ {
+ return token;
+ }
+
+ // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES2_reserved_ES2_extension_ES3_keyword(TParseContext *context, TExtension extension, int token)
+{
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.00 or GLSL ES 1.00 with enabled extension.
+ if (is_extension_enabled_or_is_core(context, 100, extension, 300))
+ {
+ return token;
+ }
+
+ // Reserved otherwise.
+ return reserved_word(yyscanner);
+}
+
+int ES3_extension(TParseContext *context, TExtension extension, int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // a keyword word in GLSL ES 3.00 with enabled extension.
+ if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(extension))
+ {
+ return token;
+ }
+
+ // Otherwise can be used as an identifier/type name
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // a keyword in GLSL ES 3.10 with enabled extension
+ if (is_extension_enabled_or_is_core(context, 310, extension, 320))
+ {
+ return token;
+ }
+ // a reserved word in GLSL ES 3.00+
+ if (context->getShaderVersion() >= 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ // Otherwise can be used as an identifier/type name
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ if (context->getShaderVersion() >= 300)
+ {
+ if (context->isExtensionEnabled(extension))
+ {
+ return token;
+ }
+ else
+ {
+ return reserved_word(yyscanner);
+ }
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context,
+ TExtension extension,
+ int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.00 with enabled extension or in GLSL ES 3.10
+ if (is_extension_enabled_or_is_core(context, 300, extension, 310))
+ {
+ return token;
+ }
+
+ if (context->getShaderVersion() == 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES3_reserved_ES3_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.00 with enabled extension or in GLSL ES 3.20
+ if (is_extension_enabled_or_is_core(context, 300, extension, 320))
+ {
+ return token;
+ }
+
+ if (context->getShaderVersion() == 300 || context->getShaderVersion() == 310)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
+ if (is_extension_enabled_or_is_core(context, 310, extension, 320))
+ {
+ return token;
+ }
+
+ // A reserved word in GLSL ES 3.10
+ if (context->getShaderVersion() == 310)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ int token1,
+ int token2)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
+ if (is_extension_enabled_or_is_core(context, 310, extension1, 320))
+ {
+ return token1;
+ }
+ else if (is_extension_enabled_or_is_core(context, 310, extension2, 320))
+ {
+ return token2;
+ }
+
+ // A reserved word in GLSL ES 3.10
+ if (context->getShaderVersion() == 310)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+static int ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ int token1,
+ int token2)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
+ if (is_extension_enabled_or_is_core(context, 310, extension1, 320))
+ {
+ return token1;
+ }
+ else if (is_extension_enabled_or_is_core(context, 310, extension2, 320))
+ {
+ return token2;
+ }
+
+ // A reserved word in GLSL ES 3.00 and 3.10
+ if (context->getShaderVersion() >= 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int uint_constant(TParseContext *context)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+
+ if (context->getShaderVersion() < 300)
+ {
+ context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext);
+ return 0;
+ }
+
+ if (!atoi_clamp(yytext, &(yylval->lex.u)))
+ yyextra->error(*yylloc, "Integer overflow", yytext);
+
+ return UINTCONSTANT;
+}
+
+int floatsuffix_check(TParseContext *context)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+
+ if (context->getShaderVersion() < 300)
+ {
+ context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext);
+ return 0;
+ }
+
+ std::string text = yytext;
+ text.resize(text.size() - 1);
+ if (!strtof_clamp(text, &(yylval->lex.f)))
+ yyextra->warning(*yylloc, "Float overflow", yytext);
+
+ return (FLOATCONSTANT);
+}
+
+void yyerror(YYLTYPE *lloc, TParseContext *context, void *scanner, const char *reason)
+{
+ context->error(*lloc, reason, yyget_text(scanner));
+}
+
+int int_constant(TParseContext *context)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+
+ unsigned int u;
+ if (!atoi_clamp(yytext, &u))
+ {
+ if (context->getShaderVersion() >= 300)
+ yyextra->error(*yylloc, "Integer overflow", yytext);
+ else
+ yyextra->warning(*yylloc, "Integer overflow", yytext);
+ }
+ yylval->lex.i = static_cast<int>(u);
+ return INTCONSTANT;
+}
+
+int float_constant(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!strtof_clamp(yytext, &(yylval->lex.f)))
+ yyextra->warning(*yylloc, "Float overflow", yytext);
+ return FLOATCONSTANT;
+}
+
+int yuvcscstandardext_constant(TParseContext *context)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an
+ // identifier/type name
+ if (context->getShaderVersion() >= 300 &&
+ context->isExtensionEnabled(TExtension::EXT_YUV_target))
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return YUVCSCSTANDARDEXTCONSTANT;
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int glslang_initialize(TParseContext *context)
+{
+ yyscan_t scanner = NULL;
+ if (yylex_init_extra(context, &scanner))
+ return 1;
+
+ context->setScanner(scanner);
+ return 0;
+}
+
+int glslang_finalize(TParseContext *context)
+{
+ yyscan_t scanner = context->getScanner();
+ if (scanner == NULL)
+ return 0;
+
+ context->setScanner(NULL);
+ yylex_destroy(scanner);
+
+ return 0;
+}
+
+int glslang_scan(size_t count,
+ const char *const string[],
+ const int length[],
+ TParseContext *context)
+{
+ yyrestart(NULL, context->getScanner());
+ yyset_column(0, context->getScanner());
+ yyset_lineno(1, context->getScanner());
+
+ // Initialize preprocessor.
+ angle::pp::Preprocessor *preprocessor = &context->getPreprocessor();
+
+ if (!preprocessor->init(count, string, length))
+ return 1;
+
+ // Define extension macros.
+ const TExtensionBehavior &extBehavior = context->extensionBehavior();
+ for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end();
+ ++iter)
+ {
+ // OVR_multiview should not be defined for WebGL spec'ed shaders.
+ if (sh::IsWebGLBasedSpec(context->getShaderSpec()) &&
+ iter->first == TExtension::OVR_multiview)
+ {
+ continue;
+ }
+ preprocessor->predefineMacro(GetExtensionNameString(iter->first), 1);
+ }
+ if (context->getFragmentPrecisionHigh())
+ preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
+
+ preprocessor->setMaxTokenSize(sh::GetGlobalMaxTokenSize(context->getShaderSpec()));
+
+ return 0;
+}
diff --git a/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.cpp b/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.cpp
new file mode 100644
index 0000000000..233b571b79
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.cpp
@@ -0,0 +1,4909 @@
+/* A Bison parser, made by GNU Bison 3.8.2. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output, and Bison version. */
+#define YYBISON 30802
+
+/* Bison version string. */
+#define YYBISON_VERSION "3.8.2"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 2
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+/* First part of user prologue. */
+
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_parser.py from glslang.y
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// glslang.y:
+// Parser for the OpenGL shading language.
+
+// Ignore errors in auto-generated code.
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wunused-function"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+# pragma GCC diagnostic ignored "-Wswitch-enum"
+#elif defined(_MSC_VER)
+# pragma warning(disable : 4065)
+# pragma warning(disable : 4189)
+# pragma warning(disable : 4244)
+# pragma warning(disable : 4505)
+# pragma warning(disable : 4701)
+# pragma warning(disable : 4702)
+#endif
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunreachable-code"
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
+#include "GLSLANG/ShaderLang.h"
+#include "angle_gl.h"
+#include "compiler/translator/Declarator.h"
+#include "compiler/translator/ParseContext.h"
+#include "compiler/translator/SymbolTable.h"
+
+#define YYENABLE_NLS 0
+
+using namespace sh;
+
+#ifndef YY_CAST
+# ifdef __cplusplus
+# define YY_CAST(Type, Val) static_cast<Type>(Val)
+# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type>(Val)
+# else
+# define YY_CAST(Type, Val) ((Type)(Val))
+# define YY_REINTERPRET_CAST(Type, Val) ((Type)(Val))
+# endif
+#endif
+#ifndef YY_NULLPTR
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# else
+# define YY_NULLPTR ((void *)0)
+# endif
+#endif
+
+#include "glslang_tab_autogen.h"
+/* Symbol kind. */
+enum yysymbol_kind_t
+{
+ YYSYMBOL_YYEMPTY = -2,
+ YYSYMBOL_YYEOF = 0, /* "end of file" */
+ YYSYMBOL_YYerror = 1, /* error */
+ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */
+ YYSYMBOL_INVARIANT = 3, /* INVARIANT */
+ YYSYMBOL_PRECISE = 4, /* PRECISE */
+ YYSYMBOL_HIGH_PRECISION = 5, /* HIGH_PRECISION */
+ YYSYMBOL_MEDIUM_PRECISION = 6, /* MEDIUM_PRECISION */
+ YYSYMBOL_LOW_PRECISION = 7, /* LOW_PRECISION */
+ YYSYMBOL_PRECISION = 8, /* PRECISION */
+ YYSYMBOL_ATTRIBUTE = 9, /* ATTRIBUTE */
+ YYSYMBOL_CONST_QUAL = 10, /* CONST_QUAL */
+ YYSYMBOL_BOOL_TYPE = 11, /* BOOL_TYPE */
+ YYSYMBOL_FLOAT_TYPE = 12, /* FLOAT_TYPE */
+ YYSYMBOL_INT_TYPE = 13, /* INT_TYPE */
+ YYSYMBOL_UINT_TYPE = 14, /* UINT_TYPE */
+ YYSYMBOL_BREAK = 15, /* BREAK */
+ YYSYMBOL_CONTINUE = 16, /* CONTINUE */
+ YYSYMBOL_DO = 17, /* DO */
+ YYSYMBOL_ELSE = 18, /* ELSE */
+ YYSYMBOL_FOR = 19, /* FOR */
+ YYSYMBOL_IF = 20, /* IF */
+ YYSYMBOL_DISCARD = 21, /* DISCARD */
+ YYSYMBOL_RETURN = 22, /* RETURN */
+ YYSYMBOL_SWITCH = 23, /* SWITCH */
+ YYSYMBOL_CASE = 24, /* CASE */
+ YYSYMBOL_DEFAULT = 25, /* DEFAULT */
+ YYSYMBOL_BVEC2 = 26, /* BVEC2 */
+ YYSYMBOL_BVEC3 = 27, /* BVEC3 */
+ YYSYMBOL_BVEC4 = 28, /* BVEC4 */
+ YYSYMBOL_IVEC2 = 29, /* IVEC2 */
+ YYSYMBOL_IVEC3 = 30, /* IVEC3 */
+ YYSYMBOL_IVEC4 = 31, /* IVEC4 */
+ YYSYMBOL_VEC2 = 32, /* VEC2 */
+ YYSYMBOL_VEC3 = 33, /* VEC3 */
+ YYSYMBOL_VEC4 = 34, /* VEC4 */
+ YYSYMBOL_UVEC2 = 35, /* UVEC2 */
+ YYSYMBOL_UVEC3 = 36, /* UVEC3 */
+ YYSYMBOL_UVEC4 = 37, /* UVEC4 */
+ YYSYMBOL_MATRIX2 = 38, /* MATRIX2 */
+ YYSYMBOL_MATRIX3 = 39, /* MATRIX3 */
+ YYSYMBOL_MATRIX4 = 40, /* MATRIX4 */
+ YYSYMBOL_IN_QUAL = 41, /* IN_QUAL */
+ YYSYMBOL_OUT_QUAL = 42, /* OUT_QUAL */
+ YYSYMBOL_INOUT_QUAL = 43, /* INOUT_QUAL */
+ YYSYMBOL_UNIFORM = 44, /* UNIFORM */
+ YYSYMBOL_BUFFER = 45, /* BUFFER */
+ YYSYMBOL_VARYING = 46, /* VARYING */
+ YYSYMBOL_MATRIX2x3 = 47, /* MATRIX2x3 */
+ YYSYMBOL_MATRIX3x2 = 48, /* MATRIX3x2 */
+ YYSYMBOL_MATRIX2x4 = 49, /* MATRIX2x4 */
+ YYSYMBOL_MATRIX4x2 = 50, /* MATRIX4x2 */
+ YYSYMBOL_MATRIX3x4 = 51, /* MATRIX3x4 */
+ YYSYMBOL_MATRIX4x3 = 52, /* MATRIX4x3 */
+ YYSYMBOL_SAMPLE = 53, /* SAMPLE */
+ YYSYMBOL_CENTROID = 54, /* CENTROID */
+ YYSYMBOL_FLAT = 55, /* FLAT */
+ YYSYMBOL_SMOOTH = 56, /* SMOOTH */
+ YYSYMBOL_NOPERSPECTIVE = 57, /* NOPERSPECTIVE */
+ YYSYMBOL_PATCH = 58, /* PATCH */
+ YYSYMBOL_READONLY = 59, /* READONLY */
+ YYSYMBOL_WRITEONLY = 60, /* WRITEONLY */
+ YYSYMBOL_COHERENT = 61, /* COHERENT */
+ YYSYMBOL_RESTRICT = 62, /* RESTRICT */
+ YYSYMBOL_VOLATILE = 63, /* VOLATILE */
+ YYSYMBOL_SHARED = 64, /* SHARED */
+ YYSYMBOL_STRUCT = 65, /* STRUCT */
+ YYSYMBOL_VOID_TYPE = 66, /* VOID_TYPE */
+ YYSYMBOL_WHILE = 67, /* WHILE */
+ YYSYMBOL_SAMPLER2D = 68, /* SAMPLER2D */
+ YYSYMBOL_SAMPLERCUBE = 69, /* SAMPLERCUBE */
+ YYSYMBOL_SAMPLER_EXTERNAL_OES = 70, /* SAMPLER_EXTERNAL_OES */
+ YYSYMBOL_SAMPLER2DRECT = 71, /* SAMPLER2DRECT */
+ YYSYMBOL_SAMPLER2DARRAY = 72, /* SAMPLER2DARRAY */
+ YYSYMBOL_ISAMPLER2D = 73, /* ISAMPLER2D */
+ YYSYMBOL_ISAMPLER3D = 74, /* ISAMPLER3D */
+ YYSYMBOL_ISAMPLERCUBE = 75, /* ISAMPLERCUBE */
+ YYSYMBOL_ISAMPLER2DARRAY = 76, /* ISAMPLER2DARRAY */
+ YYSYMBOL_USAMPLER2D = 77, /* USAMPLER2D */
+ YYSYMBOL_USAMPLER3D = 78, /* USAMPLER3D */
+ YYSYMBOL_USAMPLERCUBE = 79, /* USAMPLERCUBE */
+ YYSYMBOL_USAMPLER2DARRAY = 80, /* USAMPLER2DARRAY */
+ YYSYMBOL_SAMPLER2DMS = 81, /* SAMPLER2DMS */
+ YYSYMBOL_ISAMPLER2DMS = 82, /* ISAMPLER2DMS */
+ YYSYMBOL_USAMPLER2DMS = 83, /* USAMPLER2DMS */
+ YYSYMBOL_SAMPLER2DMSARRAY = 84, /* SAMPLER2DMSARRAY */
+ YYSYMBOL_ISAMPLER2DMSARRAY = 85, /* ISAMPLER2DMSARRAY */
+ YYSYMBOL_USAMPLER2DMSARRAY = 86, /* USAMPLER2DMSARRAY */
+ YYSYMBOL_SAMPLER3D = 87, /* SAMPLER3D */
+ YYSYMBOL_SAMPLER3DRECT = 88, /* SAMPLER3DRECT */
+ YYSYMBOL_SAMPLER2DSHADOW = 89, /* SAMPLER2DSHADOW */
+ YYSYMBOL_SAMPLERCUBESHADOW = 90, /* SAMPLERCUBESHADOW */
+ YYSYMBOL_SAMPLER2DARRAYSHADOW = 91, /* SAMPLER2DARRAYSHADOW */
+ YYSYMBOL_SAMPLERVIDEOWEBGL = 92, /* SAMPLERVIDEOWEBGL */
+ YYSYMBOL_SAMPLERCUBEARRAYOES = 93, /* SAMPLERCUBEARRAYOES */
+ YYSYMBOL_SAMPLERCUBEARRAYSHADOWOES = 94, /* SAMPLERCUBEARRAYSHADOWOES */
+ YYSYMBOL_ISAMPLERCUBEARRAYOES = 95, /* ISAMPLERCUBEARRAYOES */
+ YYSYMBOL_USAMPLERCUBEARRAYOES = 96, /* USAMPLERCUBEARRAYOES */
+ YYSYMBOL_SAMPLERCUBEARRAYEXT = 97, /* SAMPLERCUBEARRAYEXT */
+ YYSYMBOL_SAMPLERCUBEARRAYSHADOWEXT = 98, /* SAMPLERCUBEARRAYSHADOWEXT */
+ YYSYMBOL_ISAMPLERCUBEARRAYEXT = 99, /* ISAMPLERCUBEARRAYEXT */
+ YYSYMBOL_USAMPLERCUBEARRAYEXT = 100, /* USAMPLERCUBEARRAYEXT */
+ YYSYMBOL_SAMPLERBUFFER = 101, /* SAMPLERBUFFER */
+ YYSYMBOL_ISAMPLERBUFFER = 102, /* ISAMPLERBUFFER */
+ YYSYMBOL_USAMPLERBUFFER = 103, /* USAMPLERBUFFER */
+ YYSYMBOL_SAMPLEREXTERNAL2DY2YEXT = 104, /* SAMPLEREXTERNAL2DY2YEXT */
+ YYSYMBOL_IMAGE2D = 105, /* IMAGE2D */
+ YYSYMBOL_IIMAGE2D = 106, /* IIMAGE2D */
+ YYSYMBOL_UIMAGE2D = 107, /* UIMAGE2D */
+ YYSYMBOL_IMAGE3D = 108, /* IMAGE3D */
+ YYSYMBOL_IIMAGE3D = 109, /* IIMAGE3D */
+ YYSYMBOL_UIMAGE3D = 110, /* UIMAGE3D */
+ YYSYMBOL_IMAGE2DARRAY = 111, /* IMAGE2DARRAY */
+ YYSYMBOL_IIMAGE2DARRAY = 112, /* IIMAGE2DARRAY */
+ YYSYMBOL_UIMAGE2DARRAY = 113, /* UIMAGE2DARRAY */
+ YYSYMBOL_IMAGECUBE = 114, /* IMAGECUBE */
+ YYSYMBOL_IIMAGECUBE = 115, /* IIMAGECUBE */
+ YYSYMBOL_UIMAGECUBE = 116, /* UIMAGECUBE */
+ YYSYMBOL_IMAGECUBEARRAYOES = 117, /* IMAGECUBEARRAYOES */
+ YYSYMBOL_IIMAGECUBEARRAYOES = 118, /* IIMAGECUBEARRAYOES */
+ YYSYMBOL_UIMAGECUBEARRAYOES = 119, /* UIMAGECUBEARRAYOES */
+ YYSYMBOL_IMAGECUBEARRAYEXT = 120, /* IMAGECUBEARRAYEXT */
+ YYSYMBOL_IIMAGECUBEARRAYEXT = 121, /* IIMAGECUBEARRAYEXT */
+ YYSYMBOL_UIMAGECUBEARRAYEXT = 122, /* UIMAGECUBEARRAYEXT */
+ YYSYMBOL_IMAGEBUFFER = 123, /* IMAGEBUFFER */
+ YYSYMBOL_IIMAGEBUFFER = 124, /* IIMAGEBUFFER */
+ YYSYMBOL_UIMAGEBUFFER = 125, /* UIMAGEBUFFER */
+ YYSYMBOL_ATOMICUINT = 126, /* ATOMICUINT */
+ YYSYMBOL_PIXELLOCALANGLE = 127, /* PIXELLOCALANGLE */
+ YYSYMBOL_IPIXELLOCALANGLE = 128, /* IPIXELLOCALANGLE */
+ YYSYMBOL_UPIXELLOCALANGLE = 129, /* UPIXELLOCALANGLE */
+ YYSYMBOL_LAYOUT = 130, /* LAYOUT */
+ YYSYMBOL_YUVCSCSTANDARDEXT = 131, /* YUVCSCSTANDARDEXT */
+ YYSYMBOL_YUVCSCSTANDARDEXTCONSTANT = 132, /* YUVCSCSTANDARDEXTCONSTANT */
+ YYSYMBOL_IDENTIFIER = 133, /* IDENTIFIER */
+ YYSYMBOL_TYPE_NAME = 134, /* TYPE_NAME */
+ YYSYMBOL_FLOATCONSTANT = 135, /* FLOATCONSTANT */
+ YYSYMBOL_INTCONSTANT = 136, /* INTCONSTANT */
+ YYSYMBOL_UINTCONSTANT = 137, /* UINTCONSTANT */
+ YYSYMBOL_BOOLCONSTANT = 138, /* BOOLCONSTANT */
+ YYSYMBOL_FIELD_SELECTION = 139, /* FIELD_SELECTION */
+ YYSYMBOL_LEFT_OP = 140, /* LEFT_OP */
+ YYSYMBOL_RIGHT_OP = 141, /* RIGHT_OP */
+ YYSYMBOL_INC_OP = 142, /* INC_OP */
+ YYSYMBOL_DEC_OP = 143, /* DEC_OP */
+ YYSYMBOL_LE_OP = 144, /* LE_OP */
+ YYSYMBOL_GE_OP = 145, /* GE_OP */
+ YYSYMBOL_EQ_OP = 146, /* EQ_OP */
+ YYSYMBOL_NE_OP = 147, /* NE_OP */
+ YYSYMBOL_AND_OP = 148, /* AND_OP */
+ YYSYMBOL_OR_OP = 149, /* OR_OP */
+ YYSYMBOL_XOR_OP = 150, /* XOR_OP */
+ YYSYMBOL_MUL_ASSIGN = 151, /* MUL_ASSIGN */
+ YYSYMBOL_DIV_ASSIGN = 152, /* DIV_ASSIGN */
+ YYSYMBOL_ADD_ASSIGN = 153, /* ADD_ASSIGN */
+ YYSYMBOL_MOD_ASSIGN = 154, /* MOD_ASSIGN */
+ YYSYMBOL_LEFT_ASSIGN = 155, /* LEFT_ASSIGN */
+ YYSYMBOL_RIGHT_ASSIGN = 156, /* RIGHT_ASSIGN */
+ YYSYMBOL_AND_ASSIGN = 157, /* AND_ASSIGN */
+ YYSYMBOL_XOR_ASSIGN = 158, /* XOR_ASSIGN */
+ YYSYMBOL_OR_ASSIGN = 159, /* OR_ASSIGN */
+ YYSYMBOL_SUB_ASSIGN = 160, /* SUB_ASSIGN */
+ YYSYMBOL_LEFT_PAREN = 161, /* LEFT_PAREN */
+ YYSYMBOL_RIGHT_PAREN = 162, /* RIGHT_PAREN */
+ YYSYMBOL_LEFT_BRACKET = 163, /* LEFT_BRACKET */
+ YYSYMBOL_RIGHT_BRACKET = 164, /* RIGHT_BRACKET */
+ YYSYMBOL_LEFT_BRACE = 165, /* LEFT_BRACE */
+ YYSYMBOL_RIGHT_BRACE = 166, /* RIGHT_BRACE */
+ YYSYMBOL_DOT = 167, /* DOT */
+ YYSYMBOL_COMMA = 168, /* COMMA */
+ YYSYMBOL_COLON = 169, /* COLON */
+ YYSYMBOL_EQUAL = 170, /* EQUAL */
+ YYSYMBOL_SEMICOLON = 171, /* SEMICOLON */
+ YYSYMBOL_BANG = 172, /* BANG */
+ YYSYMBOL_DASH = 173, /* DASH */
+ YYSYMBOL_TILDE = 174, /* TILDE */
+ YYSYMBOL_PLUS = 175, /* PLUS */
+ YYSYMBOL_STAR = 176, /* STAR */
+ YYSYMBOL_SLASH = 177, /* SLASH */
+ YYSYMBOL_PERCENT = 178, /* PERCENT */
+ YYSYMBOL_LEFT_ANGLE = 179, /* LEFT_ANGLE */
+ YYSYMBOL_RIGHT_ANGLE = 180, /* RIGHT_ANGLE */
+ YYSYMBOL_VERTICAL_BAR = 181, /* VERTICAL_BAR */
+ YYSYMBOL_CARET = 182, /* CARET */
+ YYSYMBOL_AMPERSAND = 183, /* AMPERSAND */
+ YYSYMBOL_QUESTION = 184, /* QUESTION */
+ YYSYMBOL_YYACCEPT = 185, /* $accept */
+ YYSYMBOL_identifier = 186, /* identifier */
+ YYSYMBOL_variable_identifier = 187, /* variable_identifier */
+ YYSYMBOL_primary_expression = 188, /* primary_expression */
+ YYSYMBOL_postfix_expression = 189, /* postfix_expression */
+ YYSYMBOL_integer_expression = 190, /* integer_expression */
+ YYSYMBOL_function_call = 191, /* function_call */
+ YYSYMBOL_function_call_or_method = 192, /* function_call_or_method */
+ YYSYMBOL_function_call_generic = 193, /* function_call_generic */
+ YYSYMBOL_function_call_header_no_parameters = 194, /* function_call_header_no_parameters */
+ YYSYMBOL_function_call_header_with_parameters = 195, /* function_call_header_with_parameters */
+ YYSYMBOL_function_call_header = 196, /* function_call_header */
+ YYSYMBOL_function_identifier = 197, /* function_identifier */
+ YYSYMBOL_unary_expression = 198, /* unary_expression */
+ YYSYMBOL_unary_operator = 199, /* unary_operator */
+ YYSYMBOL_multiplicative_expression = 200, /* multiplicative_expression */
+ YYSYMBOL_additive_expression = 201, /* additive_expression */
+ YYSYMBOL_shift_expression = 202, /* shift_expression */
+ YYSYMBOL_relational_expression = 203, /* relational_expression */
+ YYSYMBOL_equality_expression = 204, /* equality_expression */
+ YYSYMBOL_and_expression = 205, /* and_expression */
+ YYSYMBOL_exclusive_or_expression = 206, /* exclusive_or_expression */
+ YYSYMBOL_inclusive_or_expression = 207, /* inclusive_or_expression */
+ YYSYMBOL_logical_and_expression = 208, /* logical_and_expression */
+ YYSYMBOL_logical_xor_expression = 209, /* logical_xor_expression */
+ YYSYMBOL_logical_or_expression = 210, /* logical_or_expression */
+ YYSYMBOL_conditional_expression = 211, /* conditional_expression */
+ YYSYMBOL_assignment_expression = 212, /* assignment_expression */
+ YYSYMBOL_assignment_operator = 213, /* assignment_operator */
+ YYSYMBOL_expression = 214, /* expression */
+ YYSYMBOL_constant_expression = 215, /* constant_expression */
+ YYSYMBOL_enter_struct = 216, /* enter_struct */
+ YYSYMBOL_declaration = 217, /* declaration */
+ YYSYMBOL_function_prototype = 218, /* function_prototype */
+ YYSYMBOL_function_declarator = 219, /* function_declarator */
+ YYSYMBOL_function_header_with_parameters = 220, /* function_header_with_parameters */
+ YYSYMBOL_function_header = 221, /* function_header */
+ YYSYMBOL_parameter_declarator = 222, /* parameter_declarator */
+ YYSYMBOL_parameter_declaration = 223, /* parameter_declaration */
+ YYSYMBOL_parameter_type_specifier = 224, /* parameter_type_specifier */
+ YYSYMBOL_init_declarator_list = 225, /* init_declarator_list */
+ YYSYMBOL_single_declaration = 226, /* single_declaration */
+ YYSYMBOL_fully_specified_type = 227, /* fully_specified_type */
+ YYSYMBOL_interpolation_qualifier = 228, /* interpolation_qualifier */
+ YYSYMBOL_type_qualifier = 229, /* type_qualifier */
+ YYSYMBOL_invariant_qualifier = 230, /* invariant_qualifier */
+ YYSYMBOL_precise_qualifier = 231, /* precise_qualifier */
+ YYSYMBOL_single_type_qualifier = 232, /* single_type_qualifier */
+ YYSYMBOL_storage_qualifier = 233, /* storage_qualifier */
+ YYSYMBOL_type_specifier = 234, /* type_specifier */
+ YYSYMBOL_precision_qualifier = 235, /* precision_qualifier */
+ YYSYMBOL_layout_qualifier = 236, /* layout_qualifier */
+ YYSYMBOL_layout_qualifier_id_list = 237, /* layout_qualifier_id_list */
+ YYSYMBOL_layout_qualifier_id = 238, /* layout_qualifier_id */
+ YYSYMBOL_type_specifier_no_prec = 239, /* type_specifier_no_prec */
+ YYSYMBOL_array_specifier = 240, /* array_specifier */
+ YYSYMBOL_type_specifier_nonarray = 241, /* type_specifier_nonarray */
+ YYSYMBOL_struct_specifier = 242, /* struct_specifier */
+ YYSYMBOL_243_1 = 243, /* $@1 */
+ YYSYMBOL_244_2 = 244, /* $@2 */
+ YYSYMBOL_struct_declaration_list = 245, /* struct_declaration_list */
+ YYSYMBOL_struct_declaration = 246, /* struct_declaration */
+ YYSYMBOL_struct_declarator_list = 247, /* struct_declarator_list */
+ YYSYMBOL_struct_declarator = 248, /* struct_declarator */
+ YYSYMBOL_initializer = 249, /* initializer */
+ YYSYMBOL_declaration_statement = 250, /* declaration_statement */
+ YYSYMBOL_statement = 251, /* statement */
+ YYSYMBOL_simple_statement = 252, /* simple_statement */
+ YYSYMBOL_compound_statement_with_scope = 253, /* compound_statement_with_scope */
+ YYSYMBOL_254_3 = 254, /* $@3 */
+ YYSYMBOL_255_4 = 255, /* $@4 */
+ YYSYMBOL_statement_no_new_scope = 256, /* statement_no_new_scope */
+ YYSYMBOL_statement_with_scope = 257, /* statement_with_scope */
+ YYSYMBOL_258_5 = 258, /* $@5 */
+ YYSYMBOL_259_6 = 259, /* $@6 */
+ YYSYMBOL_compound_statement_no_new_scope = 260, /* compound_statement_no_new_scope */
+ YYSYMBOL_statement_list = 261, /* statement_list */
+ YYSYMBOL_expression_statement = 262, /* expression_statement */
+ YYSYMBOL_selection_statement = 263, /* selection_statement */
+ YYSYMBOL_selection_rest_statement = 264, /* selection_rest_statement */
+ YYSYMBOL_switch_statement = 265, /* switch_statement */
+ YYSYMBOL_266_7 = 266, /* $@7 */
+ YYSYMBOL_case_label = 267, /* case_label */
+ YYSYMBOL_condition = 268, /* condition */
+ YYSYMBOL_iteration_statement = 269, /* iteration_statement */
+ YYSYMBOL_270_8 = 270, /* $@8 */
+ YYSYMBOL_271_9 = 271, /* $@9 */
+ YYSYMBOL_272_10 = 272, /* $@10 */
+ YYSYMBOL_for_init_statement = 273, /* for_init_statement */
+ YYSYMBOL_conditionopt = 274, /* conditionopt */
+ YYSYMBOL_for_rest_statement = 275, /* for_rest_statement */
+ YYSYMBOL_jump_statement = 276, /* jump_statement */
+ YYSYMBOL_translation_unit = 277, /* translation_unit */
+ YYSYMBOL_external_declaration = 278, /* external_declaration */
+ YYSYMBOL_function_definition = 279, /* function_definition */
+ YYSYMBOL_280_11 = 280 /* $@11 */
+};
+typedef enum yysymbol_kind_t yysymbol_kind_t;
+
+/* Second part of user prologue. */
+
+extern int yylex(YYSTYPE *yylval, YYLTYPE *yylloc, void *yyscanner);
+extern void yyerror(YYLTYPE *yylloc, TParseContext *context, void *scanner, const char *reason);
+
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ { \
+ if (N) \
+ { \
+ (Current).first_file = YYRHSLOC(Rhs, 1).first_file; \
+ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
+ (Current).last_file = YYRHSLOC(Rhs, N).last_file; \
+ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
+ } \
+ else \
+ { \
+ (Current).first_file = YYRHSLOC(Rhs, 0).last_file; \
+ (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \
+ (Current).last_file = YYRHSLOC(Rhs, 0).last_file; \
+ (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \
+ } \
+ } while (0)
+
+#define VERTEX_ONLY(S, L) \
+ do \
+ { \
+ if (context->getShaderType() != GL_VERTEX_SHADER) \
+ { \
+ context->error(L, " supported in vertex shaders only", S); \
+ } \
+ } while (0)
+
+#define COMPUTE_ONLY(S, L) \
+ do \
+ { \
+ if (context->getShaderType() != GL_COMPUTE_SHADER) \
+ { \
+ context->error(L, " supported in compute shaders only", S); \
+ } \
+ } while (0)
+
+#define ES2_ONLY(S, L) \
+ do \
+ { \
+ if (context->getShaderVersion() != 100) \
+ { \
+ context->error(L, " supported in GLSL ES 1.00 only", S); \
+ } \
+ } while (0)
+
+#define ES3_OR_NEWER(TOKEN, LINE, REASON) \
+ do \
+ { \
+ if (context->getShaderVersion() < 300) \
+ { \
+ context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN); \
+ } \
+ } while (0)
+
+#define ES3_1_OR_NEWER(TOKEN, LINE, REASON) \
+ do \
+ { \
+ if (context->getShaderVersion() < 310) \
+ { \
+ context->error(LINE, REASON " supported in GLSL ES 3.10 and above only", TOKEN); \
+ } \
+ } while (0)
+
+#ifdef short
+# undef short
+#endif
+
+/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
+ <limits.h> and (if available) <stdint.h> are included
+ so that the code can choose integer types of a good width. */
+
+#ifndef __PTRDIFF_MAX__
+# include <limits.h> /* INFRINGES ON USER NAME SPACE */
+# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_STDINT_H
+# endif
+#endif
+
+/* Narrow types that promote to a signed type and that can represent a
+ signed or unsigned integer of at least N bits. In tables they can
+ save space and decrease cache pressure. Promoting to a signed type
+ helps avoid bugs in integer arithmetic. */
+
+#ifdef __INT_LEAST8_MAX__
+typedef __INT_LEAST8_TYPE__ yytype_int8;
+#elif defined YY_STDINT_H
+typedef int_least8_t yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef __INT_LEAST16_MAX__
+typedef __INT_LEAST16_TYPE__ yytype_int16;
+#elif defined YY_STDINT_H
+typedef int_least16_t yytype_int16;
+#else
+typedef short yytype_int16;
+#endif
+
+/* Work around bug in HP-UX 11.23, which defines these macros
+ incorrectly for preprocessor constants. This workaround can likely
+ be removed in 2023, as HPE has promised support for HP-UX 11.23
+ (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
+ <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */
+#ifdef __hpux
+# undef UINT_LEAST8_MAX
+# undef UINT_LEAST16_MAX
+# define UINT_LEAST8_MAX 255
+# define UINT_LEAST16_MAX 65535
+#endif
+
+#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST8_TYPE__ yytype_uint8;
+#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H && UINT_LEAST8_MAX <= INT_MAX)
+typedef uint_least8_t yytype_uint8;
+#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
+typedef unsigned char yytype_uint8;
+#else
+typedef short yytype_uint8;
+#endif
+
+#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST16_TYPE__ yytype_uint16;
+#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H && UINT_LEAST16_MAX <= INT_MAX)
+typedef uint_least16_t yytype_uint16;
+#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
+typedef unsigned short yytype_uint16;
+#else
+typedef int yytype_uint16;
+#endif
+
+#ifndef YYPTRDIFF_T
+# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
+# define YYPTRDIFF_T __PTRDIFF_TYPE__
+# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
+# elif defined PTRDIFF_MAX
+# ifndef ptrdiff_t
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# endif
+# define YYPTRDIFF_T ptrdiff_t
+# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
+# else
+# define YYPTRDIFF_T long
+# define YYPTRDIFF_MAXIMUM LONG_MAX
+# endif
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM \
+ YY_CAST(YYPTRDIFF_T, (YYPTRDIFF_MAXIMUM < YY_CAST(YYSIZE_T, -1) ? YYPTRDIFF_MAXIMUM \
+ : YY_CAST(YYSIZE_T, -1)))
+
+#define YYSIZEOF(X) YY_CAST(YYPTRDIFF_T, sizeof(X))
+
+/* Stored state numbers (used for stacks). */
+typedef yytype_int16 yy_state_t;
+
+/* State numbers in computations. */
+typedef int yy_state_fast_t;
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_PURE __attribute__((__pure__))
+# else
+# define YY_ATTRIBUTE_PURE
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_UNUSED __attribute__((__unused__))
+# else
+# define YY_ATTRIBUTE_UNUSED
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if !defined lint || defined __GNUC__
+# define YY_USE(E) ((void)(E))
+#else
+# define YY_USE(E) /* empty */
+#endif
+
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+#if defined __GNUC__ && !defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wuninitialized\"")
+# else
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wuninitialized\"") \
+ _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# endif
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END _Pragma("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+#if defined __cplusplus && defined __GNUC__ && !defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_USELESS_CAST_BEGIN \
+ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wuseless-cast\"")
+# define YY_IGNORE_USELESS_CAST_END _Pragma("GCC diagnostic pop")
+#endif
+#ifndef YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_END
+#endif
+
+#define YY_ASSERT(E) ((void)(0 && (E)))
+
+#if !defined yyoverflow
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if !defined _ALLOCA_H && !defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+/* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+/* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) \
+ do \
+ { /* empty */ \
+ ; \
+ } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+/* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && !defined EXIT_SUCCESS && \
+ !((defined YYMALLOC || defined malloc) && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if !defined malloc && !defined EXIT_SUCCESS
+void *malloc(YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if !defined free && !defined EXIT_SUCCESS
+void free(void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* !defined yyoverflow */
+
+#if (!defined yyoverflow && \
+ (!defined __cplusplus || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL && \
+ defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yy_state_t yyss_alloc;
+ YYSTYPE yyvs_alloc;
+ YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (YYSIZEOF(union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (YYSIZEOF(yy_state_t) + YYSIZEOF(YYSTYPE) + YYSIZEOF(YYLTYPE)) + \
+ 2 * YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYPTRDIFF_T yynewbytes; \
+ YYCOPY(&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * YYSIZEOF(*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / YYSIZEOF(*yyptr); \
+ } while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy(Dst, Src, YY_CAST(YYSIZE_T, (Count)) * sizeof(*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYPTRDIFF_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 167
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 3566
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 185
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 96
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 329
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 453
+
+/* YYMAXUTOK -- Last valid token kind. */
+#define YYMAXUTOK 439
+
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
+#define YYTRANSLATE(YYX) \
+ (0 <= (YYX) && (YYX) <= YYMAXUTOK ? YY_CAST(yysymbol_kind_t, yytranslate[YYX]) \
+ : YYSYMBOL_YYUNDEF)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex. */
+static const yytype_uint8 yytranslate[] = {
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162,
+ 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
+ 182, 183, 184};
+
+#if YYDEBUG
+/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_int16 yyrline[] = {
+ 0, 259, 259, 260, 263, 270, 273, 278, 283, 288, 293, 302, 308, 311, 314, 317,
+ 320, 323, 329, 336, 342, 345, 353, 356, 362, 365, 371, 375, 382, 390, 393, 396,
+ 402, 405, 408, 411, 418, 419, 420, 421, 429, 430, 433, 436, 443, 444, 447, 453,
+ 454, 458, 465, 466, 469, 472, 475, 481, 482, 485, 491, 492, 499, 500, 507, 508,
+ 515, 516, 522, 523, 529, 530, 536, 537, 543, 544, 550, 551, 552, 553, 557, 558,
+ 559, 563, 567, 571, 575, 582, 585, 591, 598, 605, 608, 611, 615, 619, 623, 627,
+ 631, 638, 645, 648, 655, 668, 691, 701, 704, 710, 714, 718, 722, 729, 736, 739,
+ 743, 747, 752, 759, 763, 767, 771, 776, 783, 787, 793, 796, 799, 809, 813, 820,
+ 826, 832, 836, 840, 843, 846, 850, 858, 863, 867, 870, 873, 876, 879, 883, 891,
+ 894, 898, 901, 904, 907, 910, 913, 917, 924, 931, 934, 937, 943, 950, 953, 959,
+ 962, 965, 968, 974, 977, 984, 989, 996, 1001, 1012, 1015, 1018, 1021, 1024, 1027, 1031,
+ 1035, 1039, 1043, 1047, 1051, 1055, 1059, 1063, 1067, 1071, 1075, 1079, 1083, 1087, 1091, 1095,
+ 1099, 1103, 1107, 1111, 1118, 1121, 1124, 1127, 1130, 1133, 1136, 1144, 1152, 1162, 1165, 1168,
+ 1171, 1174, 1177, 1180, 1188, 1196, 1206, 1209, 1212, 1215, 1218, 1221, 1224, 1232, 1240, 1250,
+ 1253, 1256, 1259, 1267, 1275, 1282, 1292, 1299, 1306, 1309, 1312, 1315, 1318, 1321, 1324, 1327,
+ 1330, 1333, 1336, 1339, 1342, 1350, 1358, 1366, 1374, 1382, 1390, 1400, 1410, 1420, 1423, 1430,
+ 1437, 1444, 1447, 1455, 1455, 1458, 1458, 1464, 1467, 1473, 1476, 1483, 1487, 1493, 1496, 1502,
+ 1506, 1510, 1511, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1527, 1531, 1531, 1531, 1538, 1539,
+ 1543, 1543, 1544, 1544, 1549, 1553, 1560, 1564, 1571, 1572, 1576, 1582, 1586, 1595, 1595, 1602,
+ 1605, 1611, 1615, 1621, 1621, 1626, 1626, 1630, 1630, 1638, 1641, 1647, 1650, 1656, 1660, 1667,
+ 1670, 1673, 1676, 1679, 1687, 1693, 1699, 1702, 1708, 1708};
+#endif
+
+/** Accessing symbol of state STATE. */
+#define YY_ACCESSING_SYMBOL(State) YY_CAST(yysymbol_kind_t, yystos[State])
+
+#if YYDEBUG || 0
+/* The user-facing name of the symbol whose (internal) number is
+ YYSYMBOL. No bounds checking. */
+static const char *yysymbol_name(yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
+
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] = {"\"end of file\"",
+ "error",
+ "\"invalid token\"",
+ "INVARIANT",
+ "PRECISE",
+ "HIGH_PRECISION",
+ "MEDIUM_PRECISION",
+ "LOW_PRECISION",
+ "PRECISION",
+ "ATTRIBUTE",
+ "CONST_QUAL",
+ "BOOL_TYPE",
+ "FLOAT_TYPE",
+ "INT_TYPE",
+ "UINT_TYPE",
+ "BREAK",
+ "CONTINUE",
+ "DO",
+ "ELSE",
+ "FOR",
+ "IF",
+ "DISCARD",
+ "RETURN",
+ "SWITCH",
+ "CASE",
+ "DEFAULT",
+ "BVEC2",
+ "BVEC3",
+ "BVEC4",
+ "IVEC2",
+ "IVEC3",
+ "IVEC4",
+ "VEC2",
+ "VEC3",
+ "VEC4",
+ "UVEC2",
+ "UVEC3",
+ "UVEC4",
+ "MATRIX2",
+ "MATRIX3",
+ "MATRIX4",
+ "IN_QUAL",
+ "OUT_QUAL",
+ "INOUT_QUAL",
+ "UNIFORM",
+ "BUFFER",
+ "VARYING",
+ "MATRIX2x3",
+ "MATRIX3x2",
+ "MATRIX2x4",
+ "MATRIX4x2",
+ "MATRIX3x4",
+ "MATRIX4x3",
+ "SAMPLE",
+ "CENTROID",
+ "FLAT",
+ "SMOOTH",
+ "NOPERSPECTIVE",
+ "PATCH",
+ "READONLY",
+ "WRITEONLY",
+ "COHERENT",
+ "RESTRICT",
+ "VOLATILE",
+ "SHARED",
+ "STRUCT",
+ "VOID_TYPE",
+ "WHILE",
+ "SAMPLER2D",
+ "SAMPLERCUBE",
+ "SAMPLER_EXTERNAL_OES",
+ "SAMPLER2DRECT",
+ "SAMPLER2DARRAY",
+ "ISAMPLER2D",
+ "ISAMPLER3D",
+ "ISAMPLERCUBE",
+ "ISAMPLER2DARRAY",
+ "USAMPLER2D",
+ "USAMPLER3D",
+ "USAMPLERCUBE",
+ "USAMPLER2DARRAY",
+ "SAMPLER2DMS",
+ "ISAMPLER2DMS",
+ "USAMPLER2DMS",
+ "SAMPLER2DMSARRAY",
+ "ISAMPLER2DMSARRAY",
+ "USAMPLER2DMSARRAY",
+ "SAMPLER3D",
+ "SAMPLER3DRECT",
+ "SAMPLER2DSHADOW",
+ "SAMPLERCUBESHADOW",
+ "SAMPLER2DARRAYSHADOW",
+ "SAMPLERVIDEOWEBGL",
+ "SAMPLERCUBEARRAYOES",
+ "SAMPLERCUBEARRAYSHADOWOES",
+ "ISAMPLERCUBEARRAYOES",
+ "USAMPLERCUBEARRAYOES",
+ "SAMPLERCUBEARRAYEXT",
+ "SAMPLERCUBEARRAYSHADOWEXT",
+ "ISAMPLERCUBEARRAYEXT",
+ "USAMPLERCUBEARRAYEXT",
+ "SAMPLERBUFFER",
+ "ISAMPLERBUFFER",
+ "USAMPLERBUFFER",
+ "SAMPLEREXTERNAL2DY2YEXT",
+ "IMAGE2D",
+ "IIMAGE2D",
+ "UIMAGE2D",
+ "IMAGE3D",
+ "IIMAGE3D",
+ "UIMAGE3D",
+ "IMAGE2DARRAY",
+ "IIMAGE2DARRAY",
+ "UIMAGE2DARRAY",
+ "IMAGECUBE",
+ "IIMAGECUBE",
+ "UIMAGECUBE",
+ "IMAGECUBEARRAYOES",
+ "IIMAGECUBEARRAYOES",
+ "UIMAGECUBEARRAYOES",
+ "IMAGECUBEARRAYEXT",
+ "IIMAGECUBEARRAYEXT",
+ "UIMAGECUBEARRAYEXT",
+ "IMAGEBUFFER",
+ "IIMAGEBUFFER",
+ "UIMAGEBUFFER",
+ "ATOMICUINT",
+ "PIXELLOCALANGLE",
+ "IPIXELLOCALANGLE",
+ "UPIXELLOCALANGLE",
+ "LAYOUT",
+ "YUVCSCSTANDARDEXT",
+ "YUVCSCSTANDARDEXTCONSTANT",
+ "IDENTIFIER",
+ "TYPE_NAME",
+ "FLOATCONSTANT",
+ "INTCONSTANT",
+ "UINTCONSTANT",
+ "BOOLCONSTANT",
+ "FIELD_SELECTION",
+ "LEFT_OP",
+ "RIGHT_OP",
+ "INC_OP",
+ "DEC_OP",
+ "LE_OP",
+ "GE_OP",
+ "EQ_OP",
+ "NE_OP",
+ "AND_OP",
+ "OR_OP",
+ "XOR_OP",
+ "MUL_ASSIGN",
+ "DIV_ASSIGN",
+ "ADD_ASSIGN",
+ "MOD_ASSIGN",
+ "LEFT_ASSIGN",
+ "RIGHT_ASSIGN",
+ "AND_ASSIGN",
+ "XOR_ASSIGN",
+ "OR_ASSIGN",
+ "SUB_ASSIGN",
+ "LEFT_PAREN",
+ "RIGHT_PAREN",
+ "LEFT_BRACKET",
+ "RIGHT_BRACKET",
+ "LEFT_BRACE",
+ "RIGHT_BRACE",
+ "DOT",
+ "COMMA",
+ "COLON",
+ "EQUAL",
+ "SEMICOLON",
+ "BANG",
+ "DASH",
+ "TILDE",
+ "PLUS",
+ "STAR",
+ "SLASH",
+ "PERCENT",
+ "LEFT_ANGLE",
+ "RIGHT_ANGLE",
+ "VERTICAL_BAR",
+ "CARET",
+ "AMPERSAND",
+ "QUESTION",
+ "$accept",
+ "identifier",
+ "variable_identifier",
+ "primary_expression",
+ "postfix_expression",
+ "integer_expression",
+ "function_call",
+ "function_call_or_method",
+ "function_call_generic",
+ "function_call_header_no_parameters",
+ "function_call_header_with_parameters",
+ "function_call_header",
+ "function_identifier",
+ "unary_expression",
+ "unary_operator",
+ "multiplicative_expression",
+ "additive_expression",
+ "shift_expression",
+ "relational_expression",
+ "equality_expression",
+ "and_expression",
+ "exclusive_or_expression",
+ "inclusive_or_expression",
+ "logical_and_expression",
+ "logical_xor_expression",
+ "logical_or_expression",
+ "conditional_expression",
+ "assignment_expression",
+ "assignment_operator",
+ "expression",
+ "constant_expression",
+ "enter_struct",
+ "declaration",
+ "function_prototype",
+ "function_declarator",
+ "function_header_with_parameters",
+ "function_header",
+ "parameter_declarator",
+ "parameter_declaration",
+ "parameter_type_specifier",
+ "init_declarator_list",
+ "single_declaration",
+ "fully_specified_type",
+ "interpolation_qualifier",
+ "type_qualifier",
+ "invariant_qualifier",
+ "precise_qualifier",
+ "single_type_qualifier",
+ "storage_qualifier",
+ "type_specifier",
+ "precision_qualifier",
+ "layout_qualifier",
+ "layout_qualifier_id_list",
+ "layout_qualifier_id",
+ "type_specifier_no_prec",
+ "array_specifier",
+ "type_specifier_nonarray",
+ "struct_specifier",
+ "$@1",
+ "$@2",
+ "struct_declaration_list",
+ "struct_declaration",
+ "struct_declarator_list",
+ "struct_declarator",
+ "initializer",
+ "declaration_statement",
+ "statement",
+ "simple_statement",
+ "compound_statement_with_scope",
+ "$@3",
+ "$@4",
+ "statement_no_new_scope",
+ "statement_with_scope",
+ "$@5",
+ "$@6",
+ "compound_statement_no_new_scope",
+ "statement_list",
+ "expression_statement",
+ "selection_statement",
+ "selection_rest_statement",
+ "switch_statement",
+ "$@7",
+ "case_label",
+ "condition",
+ "iteration_statement",
+ "$@8",
+ "$@9",
+ "$@10",
+ "for_init_statement",
+ "conditionopt",
+ "for_rest_statement",
+ "jump_statement",
+ "translation_unit",
+ "external_declaration",
+ "function_definition",
+ "$@11",
+ YY_NULLPTR};
+
+static const char *yysymbol_name(yysymbol_kind_t yysymbol)
+{
+ return yytname[yysymbol];
+}
+#endif
+
+#define YYPACT_NINF (-397)
+
+#define yypact_value_is_default(Yyn) ((Yyn) == YYPACT_NINF)
+
+#define YYTABLE_NINF (-289)
+
+#define yytable_value_is_error(Yyn) 0
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int16 yypact[] = {
+ 3052, -397, -397, -397, -397, -397, 105, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -94, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -132, -397, -397, -397, -81, -41, -49, 3184, -90, -397, -86, -397, 1609,
+ -397, -397, -397, -397, -397, -397, -397, -397, -39, -397, 2920, -397, -397, 3432, -397, -397,
+ -397, -31, -47, -397, -26, -397, 3184, -397, -397, -397, 3184, 3, 3, -397, -35, -135,
+ -114, -397, 3184, -397, -397, 1734, -10, -397, -397, -6, 3184, -397, -397, -9, -93, -397,
+ 438, -397, -397, -397, -397, -39, -97, -397, 2193, -87, -397, -397, 3184, 3, 2497, -397,
+ -397, 7, -397, -397, -397, -397, -397, 2193, 2193, 2193, -397, -397, -397, -397, -397, -397,
+ -397, -78, -397, -397, -397, 12, -69, 2344, 8, -397, 2193, -33, -96, -116, -124, 5,
+ -12, -7, -4, 31, 30, -123, -397, 17, -397, 1888, -397, 2638, 3184, 19, -397, -47,
+ 13, 14, -397, 22, 25, 16, 2042, 28, 2193, 32, 44, 37, -397, -397, 40, -397,
+ -397, -80, -397, -81, 45, -397, -397, -397, -397, 611, -397, -397, -397, -397, -397, -397,
+ -10, 2193, -83, -397, -397, 2193, 3, -39, -76, -397, -111, -397, -397, -397, -62, -397,
+ -397, 2193, 3308, -397, -397, 2193, 46, -397, -397, -397, 2193, 2193, 2193, 2193, 2193, 2193,
+ 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, -397, -397,
+ 47, -397, 2779, -397, -397, -397, -397, -397, 48, -397, 2193, -397, -397, -48, 2193, 43,
+ -397, -397, -397, 784, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, 2193,
+ 2193, -397, -397, -397, -397, 2193, -397, -43, -10, 3, -397, -122, -397, -397, 51, 41,
+ -397, 55, -397, -397, -397, -397, -397, -33, -33, -96, -96, -116, -116, -116, -116, -124,
+ -124, 5, -12, -7, -4, 31, 30, -11, -397, -397, 150, -26, 1130, 1303, -60, -397,
+ -59, -397, 1456, 784, -397, -397, -397, -397, -397, -397, -109, -397, 2193, 57, -397, -397,
+ -397, -397, 1456, 48, -397, 41, 3, 3184, 58, 56, -397, -397, 2193, -397, 50, 61,
+ 206, -397, 60, 59, 957, -397, -55, 2193, 957, 48, -397, 2193, -397, -397, -397, 63,
+ 41, -397, -397, -397, -397};
+
+/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_int16 yydefact[] = {
+ 0, 127, 128, 153, 154, 155, 0, 135, 137, 173, 170, 171, 172, 177, 178, 179, 180, 181, 182,
+ 174, 175, 176, 183, 184, 185, 186, 187, 188, 138, 139, 140, 143, 144, 136, 189, 190, 191, 192,
+ 193, 194, 151, 141, 123, 122, 124, 142, 145, 146, 147, 148, 149, 150, 0, 169, 196, 198, 229,
+ 231, 199, 205, 206, 207, 208, 214, 215, 216, 217, 200, 209, 218, 201, 210, 219, 197, 223, 224,
+ 225, 228, 202, 226, 211, 220, 203, 227, 212, 221, 204, 213, 222, 230, 232, 233, 234, 235, 236,
+ 237, 238, 239, 240, 241, 242, 243, 244, 246, 248, 245, 247, 249, 250, 251, 252, 253, 254, 255,
+ 256, 0, 195, 258, 327, 328, 0, 99, 98, 0, 110, 115, 132, 0, 133, 134, 125, 129, 120,
+ 131, 130, 152, 163, 257, 0, 324, 326, 0, 2, 3, 261, 0, 0, 89, 0, 97, 0, 106,
+ 100, 108, 0, 109, 0, 90, 2, 116, 0, 95, 0, 126, 121, 0, 164, 1, 325, 0, 0,
+ 259, 162, 159, 0, 157, 0, 329, 101, 105, 107, 103, 111, 102, 0, 117, 88, 96, 0, 0,
+ 0, 263, 10, 4, 8, 6, 7, 9, 31, 0, 0, 0, 165, 38, 37, 39, 36, 5, 12,
+ 32, 14, 19, 20, 0, 0, 25, 0, 40, 0, 44, 47, 50, 55, 58, 60, 62, 64, 66,
+ 68, 70, 87, 0, 29, 0, 91, 0, 0, 0, 156, 0, 0, 0, 309, 0, 0, 0, 0,
+ 0, 0, 0, 0, 283, 292, 296, 40, 72, 85, 0, 272, 0, 152, 275, 294, 274, 273, 0,
+ 276, 277, 278, 279, 280, 281, 104, 0, 112, 271, 119, 0, 0, 269, 0, 267, 0, 264, 33,
+ 34, 0, 16, 17, 0, 0, 23, 22, 0, 169, 26, 28, 35, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 167, 0, 262, 0,
+ 160, 161, 158, 320, 319, 290, 311, 0, 323, 321, 0, 0, 0, 304, 307, 282, 0, 75, 76,
+ 78, 77, 80, 81, 82, 83, 84, 79, 74, 0, 0, 297, 293, 295, 114, 0, 118, 0, 270,
+ 0, 265, 0, 92, 11, 0, 18, 30, 15, 21, 27, 41, 42, 43, 46, 45, 48, 49, 53,
+ 54, 51, 52, 56, 57, 59, 61, 63, 65, 67, 69, 0, 168, 260, 0, 0, 0, 0, 0,
+ 322, 0, 303, 0, 284, 73, 86, 113, 266, 268, 93, 0, 13, 0, 0, 289, 291, 314, 313,
+ 316, 290, 301, 305, 0, 0, 0, 0, 94, 71, 0, 315, 0, 0, 300, 298, 0, 0, 0,
+ 285, 0, 317, 0, 290, 302, 0, 287, 308, 286, 0, 318, 312, 299, 306, 310};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] = {
+ -397, -51, -397, -397, -397, -397, -397, -397, -64, -397, -397, -397, -397, 42, -397, -142,
+ -140, -175, -143, -84, -75, -85, -82, -77, -73, -397, -151, -179, -397, -188, -202, -397,
+ 9, 10, -397, -397, -397, 77, 89, 90, -397, -397, -375, -397, -118, -397, -397, -121,
+ -397, -120, 239, -397, -397, 15, 0, -144, -397, -397, -397, -397, -152, -182, -32, -113,
+ -261, -150, -254, -377, -185, -397, -397, -187, -396, -397, -397, -145, -72, -141, -397, -397,
+ -397, -397, -397, -166, -397, -397, -397, -397, -397, -397, -397, -397, -397, 117, -397, -397};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] = {
+ 0, 279, 207, 208, 209, 366, 210, 211, 212, 213, 214, 215, 216, 254, 218, 219,
+ 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 255, 256, 351, 257, 231, 162,
+ 258, 259, 120, 121, 122, 151, 152, 153, 123, 124, 125, 126, 127, 128, 129, 130,
+ 131, 132, 133, 134, 174, 175, 232, 166, 136, 137, 236, 170, 190, 191, 280, 281,
+ 276, 261, 262, 263, 264, 339, 425, 445, 394, 395, 396, 446, 265, 266, 267, 433,
+ 268, 434, 269, 424, 270, 402, 328, 397, 418, 430, 431, 271, 138, 139, 140, 148};
+
+/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_int16 yytable[] = {
+ 135, 145, 155, 177, 154, 275, 163, 164, 283, 118, 119, 355, 356, 286, 230, 185, 358, 172, 235,
+ 415, 305, 306, 363, 432, 303, 304, 316, 422, 165, 146, 155, 320, 154, 163, 155, 184, 295, 272,
+ 274, 142, 143, 165, 189, 422, 188, 450, 335, 158, 143, 409, 189, 186, 188, 283, 233, 307, 308,
+ 187, 333, 444, 364, 317, 426, 444, 287, 288, 165, 163, 278, 238, 189, 144, 188, 273, 159, 239,
+ 233, 301, 156, 302, 233, 157, 230, 277, 322, 289, 173, 357, 352, 290, 147, 353, 361, 292, 275,
+ 362, 406, 230, 275, 293, 365, 367, 419, 420, 181, 182, 352, 447, 352, 352, 3, 4, 5, 352,
+ 371, 189, 189, 188, 188, 150, 352, 149, 135, 399, 165, 361, 183, 135, 407, 391, 379, 380, 381,
+ 382, 171, 360, 142, 143, 135, 176, 283, 169, 398, 298, 299, 300, 400, 118, 119, 355, 135, 309,
+ 310, 233, 135, 323, 324, 352, 412, 375, 376, 237, 135, 377, 378, 234, 383, 384, -30, 296, 135,
+ 311, 404, 405, 291, 312, 260, 313, 275, 314, 315, 318, 451, 329, 326, 327, 330, 331, 135, 334,
+ 135, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 336, 189, 338, 188, 337, -29, 217, -24,
+ 352, 350, 392, 401, -288, 421, 411, -31, 413, 428, 410, 436, 439, 437, 440, 441, 251, 370, 385,
+ 387, 443, 421, 179, 388, 427, 452, 135, 135, 386, 389, 178, 438, 284, 285, 390, 180, 141, 359,
+ 416, 408, 442, 414, 448, 429, 449, 325, 168, 417, 0, 0, 0, 297, 0, 0, 0, 275, 260,
+ 0, 403, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 0, 423,
+ 0, 0, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 423, 0, 163, 164,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 372, 373,
+ 374, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 260, 0,
+ 0, 0, 0, 260, 260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 260, 0, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260,
+ 0, 0, 0, 260, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 240, 241, 242,
+ 0, 243, 244, 245, 246, 247, 248, 249, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 250, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
+ 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 251, 252, 0, 0, 0,
+ 0, 253, 203, 204, 205, 206, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 240,
+ 241, 242, 0, 243, 244, 245, 246, 247, 248, 249, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 250, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74, 75, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 251, 354, 0,
+ 0, 0, 0, 253, 203, 204, 205, 206, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, 249, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 250, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 115, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 251,
+ 0, 0, 0, 0, 0, 253, 203, 204, 205, 206, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, 249, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 250, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 115, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0,
+ 0, 176, 0, 0, 0, 0, 0, 253, 203, 204, 205, 206, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, 249, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 250, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 113, 114, 115, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199,
+ 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 203, 204, 205, 206, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0,
+ 0, 199, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4,
+ 5, 201, 7, 8, 9, 10, 11, 12, 0, 0, 0, 253, 203, 204, 205, 206, 0, 0, 0,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 192, 193, 117, 194, 195, 196, 197, 198,
+ 0, 0, 199, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3,
+ 4, 5, 201, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 203, 204, 205, 206, 0, 0,
+ 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 0, 160, 117, 0, 9, 10, 11,
+ 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 161, 34, 35, 36, 37, 38,
+ 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 0, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 202, 9,
+ 10, 11, 12, 0, 0, 0, 203, 204, 205, 206, 0, 0, 0, 0, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 34, 35, 36,
+ 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 0, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0,
+ 319, 9, 10, 11, 12, 0, 0, 0, 203, 204, 205, 206, 0, 0, 0, 0, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 34,
+ 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53,
+ 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 113, 114, 0, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199,
+ 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201,
+ 9, 10, 11, 12, 0, 0, 0, 0, 0, 332, 203, 204, 205, 206, 0, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 34, 35,
+ 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 0, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 9,
+ 10, 11, 12, 0, 0, 0, 0, 0, 0, 203, 204, 205, 206, 0, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 34, 35, 36,
+ 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 294, 0, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 0, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 201, 7, 8,
+ 9, 10, 11, 12, 0, 0, 0, 0, 203, 204, 205, 206, 0, 0, 0, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 0,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 115, 116, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 3, 4, 5, 0, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 282, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 0, 0, 117, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 7, 8, 9, 10, 11,
+ 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 0, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 115, 116, 0, 0, 117, 0, 0, 0, 0, 0, 0, 167, 0, 0, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 393, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 0, 0, 117, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 0, 0, 117, 1, 2, 3, 4, 5,
+ 0, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 0, 0, 117, 9, 10, 11, 12, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 34, 35, 36, 37, 38, 39, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74, 75, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+ 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 0,
+ 116, 0, 368, 117, 9, 10, 11, 12, 369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0,
+ 0, 0, 34, 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 0, 116, 0, 0, 117};
+
+static const yytype_int16 yycheck[] = {
+ 0, 52, 122, 148, 122, 184, 127, 127, 190, 0, 0, 265, 273, 201, 165, 159, 277, 64, 170,
+ 396, 144, 145, 133, 419, 140, 141, 149, 402, 163, 161, 150, 233, 150, 154, 154, 170, 215, 181,
+ 182, 133, 134, 163, 162, 418, 162, 441, 248, 133, 134, 171, 170, 165, 170, 235, 163, 179, 180,
+ 171, 246, 436, 171, 184, 171, 440, 142, 143, 163, 188, 188, 162, 190, 165, 190, 170, 125, 168,
+ 163, 173, 168, 175, 163, 171, 233, 170, 236, 163, 133, 170, 168, 167, 171, 171, 168, 162, 273,
+ 171, 357, 248, 277, 168, 162, 289, 162, 162, 155, 156, 168, 162, 168, 168, 5, 6, 7, 168,
+ 293, 235, 236, 235, 236, 168, 168, 162, 122, 171, 163, 168, 161, 127, 171, 317, 305, 306, 307,
+ 308, 165, 279, 133, 134, 138, 165, 322, 141, 330, 176, 177, 178, 334, 138, 138, 403, 150, 146,
+ 147, 163, 154, 136, 137, 168, 169, 301, 302, 170, 162, 303, 304, 171, 309, 310, 161, 161, 170,
+ 183, 351, 352, 162, 182, 176, 181, 357, 148, 150, 164, 443, 161, 171, 171, 161, 171, 188, 161,
+ 190, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 169, 322, 166, 322, 161, 161, 165, 162,
+ 168, 170, 164, 169, 165, 402, 164, 161, 67, 161, 363, 162, 171, 166, 162, 18, 165, 290, 311,
+ 313, 170, 418, 154, 314, 412, 171, 235, 236, 312, 315, 150, 428, 199, 200, 316, 154, 6, 278,
+ 397, 361, 434, 395, 439, 418, 440, 239, 138, 397, -1, -1, -1, 218, -1, -1, -1, 443, 265,
+ -1, 339, -1, -1, -1, -1, -1, -1, -1, 233, -1, -1, -1, -1, -1, -1, -1, -1, 402,
+ -1, -1, -1, -1, -1, 248, -1, -1, -1, -1, -1, -1, -1, -1, -1, 418, -1, 423, 423,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 322,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 339, 298, 299,
+ 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 422, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 396, 397, -1,
+ -1, -1, -1, 402, 403, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 418, -1, -1, -1, -1, 423, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 436,
+ -1, -1, -1, 440, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
+ 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1, -1, 165, 166, -1, -1, -1,
+ -1, 171, 172, 173, 174, 175, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91,
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1, -1, 165, 166, -1,
+ -1, -1, -1, 171, 172, 173, 174, 175, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1, -1, 165,
+ -1, -1, -1, -1, -1, 171, 172, 173, 174, 175, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1,
+ -1, 165, -1, -1, -1, -1, -1, 171, 172, 173, 174, 175, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142,
+ 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 171, 172, 173, 174, 175, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
+ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1,
+ -1, 142, 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6,
+ 7, 161, 9, 10, 11, 12, 13, 14, -1, -1, -1, 171, 172, 173, 174, 175, -1, -1, -1,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
+ -1, -1, 142, 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, 5,
+ 6, 7, 161, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, 172, 173, 174, 175, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, -1, 133, 134, -1, 11, 12, 13,
+ 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, 171, 47, 48, 49, 50, 51,
+ 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, -1, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, -1, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1, 164, 11,
+ 12, 13, 14, -1, -1, -1, 172, 173, 174, 175, -1, -1, -1, -1, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, 47, 48, 49,
+ 50, 51, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, -1, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, -1, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1,
+ 164, 11, 12, 13, 14, -1, -1, -1, 172, 173, 174, 175, -1, -1, -1, -1, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, 47,
+ 48, 49, 50, 51, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66,
+ -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, -1, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142,
+ 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161,
+ 11, 12, 13, 14, -1, -1, -1, -1, -1, 171, 172, 173, 174, 175, -1, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, 47, 48,
+ 49, 50, 51, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, -1,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, -1, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, 11,
+ 12, 13, 14, -1, -1, -1, -1, -1, -1, 172, 173, 174, 175, -1, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, 47, 48, 49,
+ 50, 51, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, -1, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, -1, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, 161, 9, 10,
+ 11, 12, 13, 14, -1, -1, -1, -1, 172, 173, 174, 175, -1, -1, -1, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, -1,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, -1, -1, 134, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 3, 4, 5, 6, 7, -1, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 166, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
+ 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, -1, -1, 134, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, -1, 9, 10, 11, 12, 13,
+ 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 166, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, -1, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, -1, -1, 134, -1, -1, -1, -1, -1, -1, 0, -1, -1, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 166, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, -1, -1, 134, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, -1, -1, 134, 3, 4, 5, 6, 7,
+ -1, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
+ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, -1, -1, 134, 11, 12, 13, 14, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, 47, 48, 49, 50, 51, 52, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, -1, 68, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92,
+ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, -1,
+ 131, -1, 133, 134, 11, 12, 13, 14, 139, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1,
+ -1, -1, 47, 48, 49, 50, 51, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 65, 66, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, -1, 131, -1, -1, 134};
+
+/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
+ state STATE-NUM. */
+static const yytype_int16 yystos[] = {
+ 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 89, 90,
+ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
+ 129, 130, 131, 134, 217, 218, 219, 220, 221, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234,
+ 235, 236, 239, 241, 242, 277, 278, 279, 235, 133, 134, 165, 186, 161, 171, 280, 162, 168, 222,
+ 223, 224, 229, 234, 168, 171, 133, 186, 133, 171, 216, 232, 234, 163, 240, 0, 278, 239, 244,
+ 165, 64, 133, 237, 238, 165, 260, 223, 222, 224, 186, 186, 161, 170, 240, 165, 171, 229, 234,
+ 245, 246, 132, 133, 135, 136, 137, 138, 139, 142, 143, 161, 164, 172, 173, 174, 175, 187, 188,
+ 189, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
+ 209, 210, 211, 215, 239, 163, 171, 245, 243, 170, 162, 168, 15, 16, 17, 19, 20, 21, 22,
+ 23, 24, 25, 67, 165, 166, 171, 198, 211, 212, 214, 217, 218, 239, 250, 251, 252, 253, 261,
+ 262, 263, 265, 267, 269, 276, 240, 170, 240, 212, 249, 170, 234, 186, 247, 248, 166, 246, 198,
+ 198, 214, 142, 143, 163, 167, 162, 162, 168, 66, 212, 161, 198, 176, 177, 178, 173, 175, 140,
+ 141, 144, 145, 179, 180, 146, 147, 183, 182, 181, 148, 150, 149, 184, 164, 164, 215, 166, 245,
+ 136, 137, 238, 171, 171, 271, 161, 161, 171, 171, 214, 161, 215, 169, 161, 166, 254, 151, 152,
+ 153, 154, 155, 156, 157, 158, 159, 160, 170, 213, 168, 171, 166, 251, 249, 170, 249, 247, 240,
+ 168, 171, 133, 171, 162, 190, 214, 133, 139, 193, 212, 198, 198, 198, 200, 200, 201, 201, 202,
+ 202, 202, 202, 203, 203, 204, 205, 206, 207, 208, 209, 214, 164, 166, 257, 258, 259, 272, 214,
+ 171, 214, 169, 270, 261, 212, 212, 249, 171, 248, 171, 240, 164, 169, 67, 260, 252, 250, 262,
+ 273, 162, 162, 214, 227, 229, 268, 255, 171, 212, 161, 268, 274, 275, 257, 264, 266, 186, 162,
+ 166, 214, 171, 162, 18, 253, 170, 252, 256, 260, 162, 214, 256, 257, 249, 171};
+
+/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
+static const yytype_int16 yyr1[] = {
+ 0, 185, 186, 186, 187, 188, 188, 188, 188, 188, 188, 188, 189, 189, 189, 189, 189, 189, 190,
+ 191, 192, 192, 193, 193, 194, 194, 195, 195, 196, 197, 197, 197, 198, 198, 198, 198, 199, 199,
+ 199, 199, 200, 200, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 203, 203, 204, 204,
+ 204, 205, 205, 206, 206, 207, 207, 208, 208, 209, 209, 210, 210, 211, 211, 212, 212, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213, 213, 214, 214, 215, 216, 217, 217, 217, 217, 217, 217,
+ 217, 217, 218, 219, 219, 220, 220, 221, 222, 222, 223, 223, 223, 223, 224, 225, 225, 225, 225,
+ 225, 226, 226, 226, 226, 226, 227, 227, 228, 228, 228, 229, 229, 230, 231, 232, 232, 232, 232,
+ 232, 232, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233,
+ 234, 235, 235, 235, 236, 237, 237, 238, 238, 238, 238, 239, 239, 240, 240, 240, 240, 241, 241,
+ 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
+ 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
+ 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
+ 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
+ 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 243, 242, 244, 242, 245, 245, 246,
+ 246, 247, 247, 248, 248, 249, 250, 251, 251, 252, 252, 252, 252, 252, 252, 252, 253, 254, 255,
+ 253, 256, 256, 258, 257, 259, 257, 260, 260, 261, 261, 262, 262, 263, 264, 264, 266, 265, 267,
+ 267, 268, 268, 270, 269, 271, 269, 272, 269, 273, 273, 274, 274, 275, 275, 276, 276, 276, 276,
+ 276, 277, 277, 278, 278, 280, 279};
+
+/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
+static const yytype_int8 yyr2[] = {
+ 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 4, 1, 3, 2, 2, 1, 1, 1, 3, 2, 2, 2, 1, 2, 3, 2, 1,
+ 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, 3, 1, 3, 3, 1, 3, 3, 3, 3, 1, 3, 3, 1, 3,
+ 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 5, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 2,
+ 2, 4, 5, 6, 7, 2, 3, 2, 1, 1, 2, 3, 3, 2, 3, 2, 1, 2, 1, 1, 1, 3, 4, 6, 5, 1, 2, 3, 5, 4,
+ 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 4, 1, 3, 1, 3, 3, 1, 1, 2, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 6, 0, 5, 1, 2, 3, 4, 1, 3, 1,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 5, 1, 1, 0, 2, 0, 2, 2, 3, 1, 2, 1, 2, 5, 3,
+ 1, 0, 6, 3, 2, 1, 4, 0, 6, 0, 8, 0, 7, 1, 1, 1, 0, 2, 3, 2, 2, 2, 3, 2, 1, 2, 1, 1, 0, 3};
+
+enum
+{
+ YYENOMEM = -2
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+#define YYNOMEM goto yyexhaustedlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK(yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror(&yylloc, context, scanner, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
+
+/* Backward compatibility with an undocumented macro.
+ Use YYerror or YYUNDEF. */
+#define YYERRCODE YYUNDEF
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC(Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = YYRHSLOC(Rhs, 0).last_column; \
+ } \
+ while (0)
+#endif
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+ do \
+ { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+ } while (0)
+
+/* YYLOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+# ifndef YYLOCATION_PRINT
+
+# if defined YY_LOCATION_PRINT
+
+/* Temporary convenience wrapper in case some people defined the
+ undocumented and private YY_LOCATION_PRINT macros. */
+# define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc))
+
+# elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+
+/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
+
+YY_ATTRIBUTE_UNUSED
+static int yy_location_print_(FILE *yyo, YYLTYPE const *const yylocp)
+{
+ int res = 0;
+ int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
+ if (0 <= yylocp->first_line)
+ {
+ res += YYFPRINTF(yyo, "%d", yylocp->first_line);
+ if (0 <= yylocp->first_column)
+ res += YYFPRINTF(yyo, ".%d", yylocp->first_column);
+ }
+ if (0 <= yylocp->last_line)
+ {
+ if (yylocp->first_line < yylocp->last_line)
+ {
+ res += YYFPRINTF(yyo, "-%d", yylocp->last_line);
+ if (0 <= end_col)
+ res += YYFPRINTF(yyo, ".%d", end_col);
+ }
+ else if (0 <= end_col && yylocp->first_column < end_col)
+ res += YYFPRINTF(yyo, "-%d", end_col);
+ }
+ return res;
+}
+
+# define YYLOCATION_PRINT yy_location_print_
+
+/* Temporary convenience wrapper in case some people defined the
+ undocumented and private YY_LOCATION_PRINT macros. */
+# define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc))
+
+# else
+
+# define YYLOCATION_PRINT(File, Loc) ((void)0)
+/* Temporary convenience wrapper in case some people defined the
+ undocumented and private YY_LOCATION_PRINT macros. */
+# define YY_LOCATION_PRINT YYLOCATION_PRINT
+
+# endif
+# endif /* !defined YYLOCATION_PRINT */
+
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
+ do \
+ { \
+ if (yydebug) \
+ { \
+ YYFPRINTF(stderr, "%s ", Title); \
+ yy_symbol_print(stderr, Kind, Value, Location, context, scanner); \
+ YYFPRINTF(stderr, "\n"); \
+ } \
+ } while (0)
+
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
+
+static void yy_symbol_value_print(FILE *yyo,
+ yysymbol_kind_t yykind,
+ YYSTYPE const *const yyvaluep,
+ YYLTYPE const *const yylocationp,
+ TParseContext *context,
+ void *scanner)
+{
+ FILE *yyoutput = yyo;
+ YY_USE(yyoutput);
+ YY_USE(yylocationp);
+ YY_USE(context);
+ YY_USE(scanner);
+ if (!yyvaluep)
+ return;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YY_USE(yykind);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
+
+static void yy_symbol_print(FILE *yyo,
+ yysymbol_kind_t yykind,
+ YYSTYPE const *const yyvaluep,
+ YYLTYPE const *const yylocationp,
+ TParseContext *context,
+ void *scanner)
+{
+ YYFPRINTF(yyo, "%s %s (", yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name(yykind));
+
+ YYLOCATION_PRINT(yyo, yylocationp);
+ YYFPRINTF(yyo, ": ");
+ yy_symbol_value_print(yyo, yykind, yyvaluep, yylocationp, context, scanner);
+ YYFPRINTF(yyo, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void yy_stack_print(yy_state_t *yybottom, yy_state_t *yytop)
+{
+ YYFPRINTF(stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF(stderr, " %d", yybot);
+ }
+ YYFPRINTF(stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+ do \
+ { \
+ if (yydebug) \
+ yy_stack_print((Bottom), (Top)); \
+ } while (0)
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void yy_reduce_print(yy_state_t *yyssp,
+ YYSTYPE *yyvsp,
+ YYLTYPE *yylsp,
+ int yyrule,
+ TParseContext *context,
+ void *scanner)
+{
+ int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF(stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF(stderr, " $%d = ", yyi + 1);
+ yy_symbol_print(stderr, YY_ACCESSING_SYMBOL(+yyssp[yyi + 1 - yynrhs]),
+ &yyvsp[(yyi + 1) - (yynrhs)], &(yylsp[(yyi + 1) - (yynrhs)]), context,
+ scanner);
+ YYFPRINTF(stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+ do \
+ { \
+ if (yydebug) \
+ yy_reduce_print(yyssp, yyvsp, yylsp, Rule, context, scanner); \
+ } while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args) ((void)0)
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void yydestruct(const char *yymsg,
+ yysymbol_kind_t yykind,
+ YYSTYPE *yyvaluep,
+ YYLTYPE *yylocationp,
+ TParseContext *context,
+ void *scanner)
+{
+ YY_USE(yyvaluep);
+ YY_USE(yylocationp);
+ YY_USE(context);
+ YY_USE(scanner);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT(yymsg, yykind, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YY_USE(yykind);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int yyparse(TParseContext *context, void *scanner)
+{
+ /* Lookahead token kind. */
+ int yychar;
+
+ /* The semantic value of the lookahead symbol. */
+ /* Default value used for initialization, for pacifying older GCCs
+ or non-GCC compilers. */
+ YY_INITIAL_VALUE(static YYSTYPE yyval_default;)
+ YYSTYPE yylval YY_INITIAL_VALUE(= yyval_default);
+
+ /* Location data for the lookahead symbol. */
+ static YYLTYPE yyloc_default
+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+ = {1, 1, 1, 1}
+#endif
+ ;
+ YYLTYPE yylloc = yyloc_default;
+
+ /* Number of syntax errors so far. */
+ int yynerrs = 0;
+
+ yy_state_fast_t yystate = 0;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus = 0;
+
+ /* Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* Their size. */
+ YYPTRDIFF_T yystacksize = YYINITDEPTH;
+
+ /* The state stack: array, bottom, top. */
+ yy_state_t yyssa[YYINITDEPTH];
+ yy_state_t *yyss = yyssa;
+ yy_state_t *yyssp = yyss;
+
+ /* The semantic value stack: array, bottom, top. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp = yyvs;
+
+ /* The location stack: array, bottom, top. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp = yyls;
+
+ int yyn;
+ /* The return value of yyparse. */
+ int yyresult;
+ /* Lookahead symbol kind. */
+ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[3];
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ YYDPRINTF((stderr, "Starting parse\n"));
+
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ yylsp[0] = yylloc;
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+/*--------------------------------------------------------------------.
+| yysetstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ YYDPRINTF((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT(0 <= yystate && yystate < YYNSTATES);
+ YY_IGNORE_USELESS_CAST_BEGIN
+ *yyssp = YY_CAST(yy_state_t, yystate);
+ YY_IGNORE_USELESS_CAST_END
+ YY_STACK_PRINT(yyss, yyssp);
+
+ if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ YYNOMEM;
+#else
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYPTRDIFF_T yysize = yyssp - yyss + 1;
+
+# if defined yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ yy_state_t *yyss1 = yyss;
+ YYSTYPE *yyvs1 = yyvs;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow(YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF(*yyssp), &yyvs1,
+ yysize * YYSIZEOF(*yyvsp), &yyls1, yysize * YYSIZEOF(*yylsp), &yystacksize);
+ yyss = yyss1;
+ yyvs = yyvs1;
+ yyls = yyls1;
+ }
+# else /* defined YYSTACK_RELOCATE */
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ YYNOMEM;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yy_state_t *yyss1 = yyss;
+ union yyalloc *yyptr = YY_CAST(
+ union yyalloc *, YYSTACK_ALLOC(YY_CAST(YYSIZE_T, YYSTACK_BYTES(yystacksize))));
+ if (!yyptr)
+ YYNOMEM;
+ YYSTACK_RELOCATE(yyss_alloc, yyss);
+ YYSTACK_RELOCATE(yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE(yyls_alloc, yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE(yyss1);
+ }
+# endif
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YY_IGNORE_USELESS_CAST_BEGIN
+ YYDPRINTF((stderr, "Stack size increased to %ld\n", YY_CAST(long, yystacksize)));
+ YY_IGNORE_USELESS_CAST_END
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default(yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF((stderr, "Reading a token\n"));
+ yychar = yylex(&yylval, &yylloc, scanner);
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = YYEOF;
+ yytoken = YYSYMBOL_YYEOF;
+ YYDPRINTF((stderr, "Now at end of input.\n"));
+ }
+ else if (yychar == YYerror)
+ {
+ /* The scanner already issued an error message, process directly
+ to error recovery. But do not keep the error token as
+ lookahead, it is too special and may lead us to an endless
+ loop in error recovery. */
+ yychar = YYUNDEF;
+ yytoken = YYSYMBOL_YYerror;
+ yyerror_range[1] = yylloc;
+ goto yyerrlab1;
+ }
+ else
+ {
+ yytoken = YYTRANSLATE(yychar);
+ YY_SYMBOL_PRINT("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error(yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT("Shifting", yytoken, &yylval, &yylloc);
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+ *++yylsp = yylloc;
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+ goto yynewstate;
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+/*-----------------------------.
+| yyreduce -- do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1 - yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT(yyloc, (yylsp - yylen), yylen);
+ yyerror_range[1] = yyloc;
+ YY_REDUCE_PRINT(yyn);
+ switch (yyn)
+ {
+ case 4: /* variable_identifier: IDENTIFIER */
+ {
+ // The symbol table search was done in the lexical phase
+ (yyval.interm.intermTypedNode) = context->parseVariableIdentifier(
+ (yylsp[0]), ImmutableString((yyvsp[0].lex).string), (yyvsp[0].lex).symbol);
+ }
+ break;
+
+ case 5: /* primary_expression: variable_identifier */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 6: /* primary_expression: INTCONSTANT */
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setIConst((yyvsp[0].lex).i);
+ (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
+ }
+ break;
+
+ case 7: /* primary_expression: UINTCONSTANT */
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setUConst((yyvsp[0].lex).u);
+ (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
+ }
+ break;
+
+ case 8: /* primary_expression: FLOATCONSTANT */
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setFConst((yyvsp[0].lex).f);
+ (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
+ }
+ break;
+
+ case 9: /* primary_expression: BOOLCONSTANT */
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setBConst((yyvsp[0].lex).b);
+ (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
+ }
+ break;
+
+ case 10: /* primary_expression: YUVCSCSTANDARDEXTCONSTANT */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]), TExtension::EXT_YUV_target))
+ {
+ context->error((yylsp[0]), "unsupported value",
+ ImmutableString((yyvsp[0].lex).string));
+ }
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setYuvCscStandardEXTConst(
+ getYuvCscStandardEXT(ImmutableString((yyvsp[0].lex).string)));
+ (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
+ }
+ break;
+
+ case 11: /* primary_expression: LEFT_PAREN expression RIGHT_PAREN */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode);
+ }
+ break;
+
+ case 12: /* postfix_expression: primary_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 13: /* postfix_expression: postfix_expression LEFT_BRACKET integer_expression
+ RIGHT_BRACKET */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addIndexExpression((yyvsp[-3].interm.intermTypedNode), (yylsp[-2]),
+ (yyvsp[-1].interm.intermTypedNode));
+ }
+ break;
+
+ case 14: /* postfix_expression: function_call */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 15: /* postfix_expression: postfix_expression DOT FIELD_SELECTION */
+ {
+ (yyval.interm.intermTypedNode) = context->addFieldSelectionExpression(
+ (yyvsp[-2].interm.intermTypedNode), (yylsp[-1]),
+ ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
+ }
+ break;
+
+ case 16: /* postfix_expression: postfix_expression INC_OP */
+ {
+ (yyval.interm.intermTypedNode) = context->addUnaryMathLValue(
+ EOpPostIncrement, (yyvsp[-1].interm.intermTypedNode), (yylsp[0]));
+ }
+ break;
+
+ case 17: /* postfix_expression: postfix_expression DEC_OP */
+ {
+ (yyval.interm.intermTypedNode) = context->addUnaryMathLValue(
+ EOpPostDecrement, (yyvsp[-1].interm.intermTypedNode), (yylsp[0]));
+ }
+ break;
+
+ case 18: /* integer_expression: expression */
+ {
+ context->checkIsScalarInteger((yyvsp[0].interm.intermTypedNode), "[]");
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 19: /* function_call: function_call_or_method */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addFunctionCallOrMethod((yyvsp[0].interm.functionLookup), (yylsp[0]));
+ }
+ break;
+
+ case 20: /* function_call_or_method: function_call_generic */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[0].interm.functionLookup);
+ }
+ break;
+
+ case 21: /* function_call_or_method: postfix_expression DOT function_call_generic */
+ {
+ ES3_OR_NEWER("", (yylsp[0]), "methods");
+ (yyval.interm.functionLookup) = (yyvsp[0].interm.functionLookup);
+ (yyval.interm.functionLookup)->setThisNode((yyvsp[-2].interm.intermTypedNode));
+ }
+ break;
+
+ case 22: /* function_call_generic: function_call_header_with_parameters RIGHT_PAREN */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-1].interm.functionLookup);
+ }
+ break;
+
+ case 23: /* function_call_generic: function_call_header_no_parameters RIGHT_PAREN */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-1].interm.functionLookup);
+ }
+ break;
+
+ case 24: /* function_call_header_no_parameters: function_call_header VOID_TYPE */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-1].interm.functionLookup);
+ }
+ break;
+
+ case 25: /* function_call_header_no_parameters: function_call_header */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[0].interm.functionLookup);
+ }
+ break;
+
+ case 26: /* function_call_header_with_parameters: function_call_header assignment_expression
+ */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-1].interm.functionLookup);
+ (yyval.interm.functionLookup)->addArgument((yyvsp[0].interm.intermTypedNode));
+ }
+ break;
+
+ case 27: /* function_call_header_with_parameters: function_call_header_with_parameters COMMA
+ assignment_expression */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-2].interm.functionLookup);
+ (yyval.interm.functionLookup)->addArgument((yyvsp[0].interm.intermTypedNode));
+ }
+ break;
+
+ case 28: /* function_call_header: function_identifier LEFT_PAREN */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-1].interm.functionLookup);
+ }
+ break;
+
+ case 29: /* function_identifier: type_specifier_no_prec */
+ {
+ (yyval.interm.functionLookup) = context->addConstructorFunc((yyvsp[0].interm.type));
+ }
+ break;
+
+ case 30: /* function_identifier: IDENTIFIER */
+ {
+ (yyval.interm.functionLookup) = context->addNonConstructorFunc(
+ ImmutableString((yyvsp[0].lex).string), (yyvsp[0].lex).symbol);
+ }
+ break;
+
+ case 31: /* function_identifier: FIELD_SELECTION */
+ {
+ (yyval.interm.functionLookup) = context->addNonConstructorFunc(
+ ImmutableString((yyvsp[0].lex).string), (yyvsp[0].lex).symbol);
+ }
+ break;
+
+ case 32: /* unary_expression: postfix_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 33: /* unary_expression: INC_OP unary_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addUnaryMathLValue(
+ EOpPreIncrement, (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 34: /* unary_expression: DEC_OP unary_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addUnaryMathLValue(
+ EOpPreDecrement, (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 35: /* unary_expression: unary_operator unary_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addUnaryMath(
+ (yyvsp[-1].interm.op), (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 36: /* unary_operator: PLUS */
+ {
+ (yyval.interm.op) = EOpPositive;
+ }
+ break;
+
+ case 37: /* unary_operator: DASH */
+ {
+ (yyval.interm.op) = EOpNegative;
+ }
+ break;
+
+ case 38: /* unary_operator: BANG */
+ {
+ (yyval.interm.op) = EOpLogicalNot;
+ }
+ break;
+
+ case 39: /* unary_operator: TILDE */
+ {
+ ES3_OR_NEWER("~", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitwiseNot;
+ }
+ break;
+
+ case 40: /* multiplicative_expression: unary_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 41: /* multiplicative_expression: multiplicative_expression STAR unary_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpMul, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 42: /* multiplicative_expression: multiplicative_expression SLASH unary_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpDiv, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 43: /* multiplicative_expression: multiplicative_expression PERCENT unary_expression */
+ {
+ ES3_OR_NEWER("%", (yylsp[-1]), "integer modulus operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpIMod, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 44: /* additive_expression: multiplicative_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 45: /* additive_expression: additive_expression PLUS multiplicative_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpAdd, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 46: /* additive_expression: additive_expression DASH multiplicative_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpSub, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 47: /* shift_expression: additive_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 48: /* shift_expression: shift_expression LEFT_OP additive_expression */
+ {
+ ES3_OR_NEWER("<<", (yylsp[-1]), "bit-wise operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpBitShiftLeft, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 49: /* shift_expression: shift_expression RIGHT_OP additive_expression */
+ {
+ ES3_OR_NEWER(">>", (yylsp[-1]), "bit-wise operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpBitShiftRight, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 50: /* relational_expression: shift_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 51: /* relational_expression: relational_expression LEFT_ANGLE shift_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMathBooleanResult(EOpLessThan, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 52: /* relational_expression: relational_expression RIGHT_ANGLE shift_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpGreaterThan, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 53: /* relational_expression: relational_expression LE_OP shift_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpLessThanEqual, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 54: /* relational_expression: relational_expression GE_OP shift_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpGreaterThanEqual, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 55: /* equality_expression: relational_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 56: /* equality_expression: equality_expression EQ_OP relational_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMathBooleanResult(EOpEqual, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 57: /* equality_expression: equality_expression NE_OP relational_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMathBooleanResult(EOpNotEqual, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 58: /* and_expression: equality_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 59: /* and_expression: and_expression AMPERSAND equality_expression */
+ {
+ ES3_OR_NEWER("&", (yylsp[-1]), "bit-wise operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpBitwiseAnd, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 60: /* exclusive_or_expression: and_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 61: /* exclusive_or_expression: exclusive_or_expression CARET and_expression */
+ {
+ ES3_OR_NEWER("^", (yylsp[-1]), "bit-wise operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpBitwiseXor, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 62: /* inclusive_or_expression: exclusive_or_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 63: /* inclusive_or_expression: inclusive_or_expression VERTICAL_BAR
+ exclusive_or_expression */
+ {
+ ES3_OR_NEWER("|", (yylsp[-1]), "bit-wise operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpBitwiseOr, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 64: /* logical_and_expression: inclusive_or_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 65: /* logical_and_expression: logical_and_expression AND_OP inclusive_or_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpLogicalAnd, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 66: /* logical_xor_expression: logical_and_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 67: /* logical_xor_expression: logical_xor_expression XOR_OP logical_and_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpLogicalXor, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 68: /* logical_or_expression: logical_xor_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 69: /* logical_or_expression: logical_or_expression OR_OP logical_xor_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpLogicalOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode),
+ (yylsp[-1]));
+ }
+ break;
+
+ case 70: /* conditional_expression: logical_or_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 71: /* conditional_expression: logical_or_expression QUESTION expression COLON
+ assignment_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addTernarySelection(
+ (yyvsp[-4].interm.intermTypedNode), (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-3]));
+ }
+ break;
+
+ case 72: /* assignment_expression: conditional_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 73: /* assignment_expression: unary_expression assignment_operator
+ assignment_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addAssign((yyvsp[-1].interm.op), (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 74: /* assignment_operator: EQUAL */
+ {
+ (yyval.interm.op) = EOpAssign;
+ }
+ break;
+
+ case 75: /* assignment_operator: MUL_ASSIGN */
+ {
+ (yyval.interm.op) = EOpMulAssign;
+ }
+ break;
+
+ case 76: /* assignment_operator: DIV_ASSIGN */
+ {
+ (yyval.interm.op) = EOpDivAssign;
+ }
+ break;
+
+ case 77: /* assignment_operator: MOD_ASSIGN */
+ {
+ ES3_OR_NEWER("%=", (yyloc), "integer modulus operator");
+ (yyval.interm.op) = EOpIModAssign;
+ }
+ break;
+
+ case 78: /* assignment_operator: ADD_ASSIGN */
+ {
+ (yyval.interm.op) = EOpAddAssign;
+ }
+ break;
+
+ case 79: /* assignment_operator: SUB_ASSIGN */
+ {
+ (yyval.interm.op) = EOpSubAssign;
+ }
+ break;
+
+ case 80: /* assignment_operator: LEFT_ASSIGN */
+ {
+ ES3_OR_NEWER("<<=", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitShiftLeftAssign;
+ }
+ break;
+
+ case 81: /* assignment_operator: RIGHT_ASSIGN */
+ {
+ ES3_OR_NEWER(">>=", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitShiftRightAssign;
+ }
+ break;
+
+ case 82: /* assignment_operator: AND_ASSIGN */
+ {
+ ES3_OR_NEWER("&=", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitwiseAndAssign;
+ }
+ break;
+
+ case 83: /* assignment_operator: XOR_ASSIGN */
+ {
+ ES3_OR_NEWER("^=", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitwiseXorAssign;
+ }
+ break;
+
+ case 84: /* assignment_operator: OR_ASSIGN */
+ {
+ ES3_OR_NEWER("|=", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitwiseOrAssign;
+ }
+ break;
+
+ case 85: /* expression: assignment_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 86: /* expression: expression COMMA assignment_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addComma(
+ (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 87: /* constant_expression: conditional_expression */
+ {
+ context->checkIsConst((yyvsp[0].interm.intermTypedNode));
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 88: /* enter_struct: IDENTIFIER LEFT_BRACE */
+ {
+ context->enterStructDeclaration((yylsp[-1]), ImmutableString((yyvsp[-1].lex).string));
+ (yyval.lex) = (yyvsp[-1].lex);
+ }
+ break;
+
+ case 89: /* declaration: function_prototype SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addFunctionPrototypeDeclaration(
+ *((yyvsp[-1].interm).function), (yylsp[-1]));
+ }
+ break;
+
+ case 90: /* declaration: init_declarator_list SEMICOLON */
+ {
+ (yyval.interm.intermNode) = (yyvsp[-1].interm).intermDeclaration;
+ }
+ break;
+
+ case 91: /* declaration: PRECISION precision_qualifier type_specifier_no_prec SEMICOLON */
+ {
+ context->parseDefaultPrecisionQualifier((yyvsp[-2].interm.precision),
+ (yyvsp[-1].interm.type), (yylsp[-3]));
+ (yyval.interm.intermNode) = nullptr;
+ }
+ break;
+
+ case 92: /* declaration: type_qualifier enter_struct struct_declaration_list RIGHT_BRACE
+ SEMICOLON */
+ {
+ ES3_OR_NEWER(ImmutableString((yyvsp[-3].lex).string), (yylsp[-4]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock(
+ *(yyvsp[-4].interm.typeQualifierBuilder), (yylsp[-3]),
+ ImmutableString((yyvsp[-3].lex).string), (yyvsp[-2].interm.fieldList),
+ kEmptyImmutableString, (yyloc), NULL, (yyloc));
+ }
+ break;
+
+ case 93: /* declaration: type_qualifier enter_struct struct_declaration_list RIGHT_BRACE
+ IDENTIFIER SEMICOLON */
+ {
+ ES3_OR_NEWER(ImmutableString((yyvsp[-4].lex).string), (yylsp[-5]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock(
+ *(yyvsp[-5].interm.typeQualifierBuilder), (yylsp[-4]),
+ ImmutableString((yyvsp[-4].lex).string), (yyvsp[-3].interm.fieldList),
+ ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]), NULL, (yyloc));
+ }
+ break;
+
+ case 94: /* declaration: type_qualifier enter_struct struct_declaration_list RIGHT_BRACE
+ IDENTIFIER array_specifier SEMICOLON */
+ {
+ ES3_OR_NEWER(ImmutableString((yyvsp[-5].lex).string), (yylsp[-6]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock(
+ *(yyvsp[-6].interm.typeQualifierBuilder), (yylsp[-5]),
+ ImmutableString((yyvsp[-5].lex).string), (yyvsp[-4].interm.fieldList),
+ ImmutableString((yyvsp[-2].lex).string), (yylsp[-2]), (yyvsp[-1].interm.arraySizes),
+ (yylsp[-1]));
+ }
+ break;
+
+ case 95: /* declaration: type_qualifier SEMICOLON */
+ {
+ context->parseGlobalLayoutQualifier(*(yyvsp[-1].interm.typeQualifierBuilder));
+ (yyval.interm.intermNode) = nullptr;
+ }
+ break;
+
+ case 96: /* declaration: type_qualifier IDENTIFIER SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->parseGlobalQualifierDeclaration(
+ *(yyvsp[-2].interm.typeQualifierBuilder), (yylsp[-1]),
+ ImmutableString((yyvsp[-1].lex).string), (yyvsp[-1].lex).symbol);
+ }
+ break;
+
+ case 97: /* function_prototype: function_declarator RIGHT_PAREN */
+ {
+ (yyval.interm).function =
+ context->parseFunctionDeclarator((yylsp[0]), (yyvsp[-1].interm.function));
+ context->exitFunctionDeclaration();
+ }
+ break;
+
+ case 98: /* function_declarator: function_header */
+ {
+ (yyval.interm.function) = (yyvsp[0].interm.function);
+ }
+ break;
+
+ case 99: /* function_declarator: function_header_with_parameters */
+ {
+ (yyval.interm.function) = (yyvsp[0].interm.function);
+ }
+ break;
+
+ case 100: /* function_header_with_parameters: function_header parameter_declaration */
+ {
+ // Add the parameter
+ (yyval.interm.function) = (yyvsp[-1].interm.function);
+ if ((yyvsp[0].interm.param).type->getBasicType() != EbtVoid)
+ {
+ (yyvsp[-1].interm.function)
+ ->addParameter((yyvsp[0].interm.param).createVariable(&context->symbolTable));
+ }
+ else
+ {
+ // Remember that void was seen, so error can be generated if another parameter is
+ // seen.
+ (yyvsp[-1].interm.function)->setHasVoidParameter();
+ }
+ }
+ break;
+
+ case 101: /* function_header_with_parameters: function_header_with_parameters COMMA
+ parameter_declaration */
+ {
+ (yyval.interm.function) = (yyvsp[-2].interm.function);
+ // Only first parameter of one-parameter functions can be void
+ // The check for named parameters not being void is done in parameter_declarator
+ if ((yyvsp[0].interm.param).type->getBasicType() == EbtVoid)
+ {
+ // This parameter > first is void
+ context->error((yylsp[-1]), "cannot be a parameter type except for '(void)'",
+ "void");
+ }
+ else
+ {
+ if ((yyvsp[-2].interm.function)->hasVoidParameter())
+ {
+ // Only first parameter of one-parameter functions can be void. This check
+ // prevents (void, non_void) parameters.
+ context->error((yylsp[-1]), "cannot be a parameter type except for '(void)'",
+ "void");
+ }
+ (yyvsp[-2].interm.function)
+ ->addParameter((yyvsp[0].interm.param).createVariable(&context->symbolTable));
+ }
+ }
+ break;
+
+ case 102: /* function_header: fully_specified_type IDENTIFIER LEFT_PAREN */
+ {
+ (yyval.interm.function) = context->parseFunctionHeader(
+ (yyvsp[-2].interm.type), ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]));
+
+ context->symbolTable.push();
+ context->enterFunctionDeclaration();
+ }
+ break;
+
+ case 103: /* parameter_declarator: type_specifier identifier */
+ {
+ (yyval.interm.param) = context->parseParameterDeclarator(
+ (yyvsp[-1].interm.type), ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
+ }
+ break;
+
+ case 104: /* parameter_declarator: type_specifier identifier array_specifier */
+ {
+ (yyval.interm.param) = context->parseParameterArrayDeclarator(
+ ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]),
+ *((yyvsp[0].interm.arraySizes)), (yylsp[0]), &(yyvsp[-2].interm.type));
+ }
+ break;
+
+ case 105: /* parameter_declaration: type_qualifier parameter_declarator */
+ {
+ (yyval.interm.param) = (yyvsp[0].interm.param);
+ context->checkIsParameterQualifierValid(
+ (yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.param).type);
+ }
+ break;
+
+ case 106: /* parameter_declaration: parameter_declarator */
+ {
+ (yyval.interm.param) = (yyvsp[0].interm.param);
+ (yyval.interm.param).type->setQualifier(EvqParamIn);
+ }
+ break;
+
+ case 107: /* parameter_declaration: type_qualifier parameter_type_specifier */
+ {
+ (yyval.interm.param) = (yyvsp[0].interm.param);
+ context->checkIsParameterQualifierValid(
+ (yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.param).type);
+ }
+ break;
+
+ case 108: /* parameter_declaration: parameter_type_specifier */
+ {
+ (yyval.interm.param) = (yyvsp[0].interm.param);
+ (yyval.interm.param).type->setQualifier(EvqParamIn);
+ }
+ break;
+
+ case 109: /* parameter_type_specifier: type_specifier */
+ {
+ TParameter param = {0, new TType((yyvsp[0].interm.type))};
+ (yyval.interm.param) = param;
+ }
+ break;
+
+ case 110: /* init_declarator_list: single_declaration */
+ {
+ (yyval.interm) = (yyvsp[0].interm);
+ }
+ break;
+
+ case 111: /* init_declarator_list: init_declarator_list COMMA identifier */
+ {
+ (yyval.interm) = (yyvsp[-2].interm);
+ context->parseDeclarator((yyval.interm).type, (yylsp[0]),
+ ImmutableString((yyvsp[0].lex).string),
+ (yyval.interm).intermDeclaration);
+ }
+ break;
+
+ case 112: /* init_declarator_list: init_declarator_list COMMA identifier array_specifier */
+ {
+ (yyval.interm) = (yyvsp[-3].interm);
+ context->parseArrayDeclarator(
+ (yyval.interm).type, (yylsp[-1]), ImmutableString((yyvsp[-1].lex).string),
+ (yylsp[0]), *((yyvsp[0].interm.arraySizes)), (yyval.interm).intermDeclaration);
+ }
+ break;
+
+ case 113: /* init_declarator_list: init_declarator_list COMMA identifier array_specifier
+ EQUAL initializer */
+ {
+ ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
+ (yyval.interm) = (yyvsp[-5].interm);
+ context->parseArrayInitDeclarator(
+ (yyval.interm).type, (yylsp[-3]), ImmutableString((yyvsp[-3].lex).string),
+ (yylsp[-2]), *((yyvsp[-2].interm.arraySizes)), (yylsp[-1]),
+ (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+ }
+ break;
+
+ case 114: /* init_declarator_list: init_declarator_list COMMA identifier EQUAL initializer
+ */
+ {
+ (yyval.interm) = (yyvsp[-4].interm);
+ context->parseInitDeclarator(
+ (yyval.interm).type, (yylsp[-2]), ImmutableString((yyvsp[-2].lex).string),
+ (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+ }
+ break;
+
+ case 115: /* single_declaration: fully_specified_type */
+ {
+ (yyval.interm).type = (yyvsp[0].interm.type);
+ (yyval.interm).intermDeclaration = context->parseSingleDeclaration(
+ (yyval.interm).type, (yylsp[0]), kEmptyImmutableString);
+ }
+ break;
+
+ case 116: /* single_declaration: fully_specified_type identifier */
+ {
+ (yyval.interm).type = (yyvsp[-1].interm.type);
+ (yyval.interm).intermDeclaration = context->parseSingleDeclaration(
+ (yyval.interm).type, (yylsp[0]), ImmutableString((yyvsp[0].lex).string));
+ }
+ break;
+
+ case 117: /* single_declaration: fully_specified_type identifier array_specifier */
+ {
+ (yyval.interm).type = (yyvsp[-2].interm.type);
+ (yyval.interm).intermDeclaration = context->parseSingleArrayDeclaration(
+ (yyval.interm).type, (yylsp[-1]), ImmutableString((yyvsp[-1].lex).string),
+ (yylsp[0]), *((yyvsp[0].interm.arraySizes)));
+ }
+ break;
+
+ case 118: /* single_declaration: fully_specified_type identifier array_specifier EQUAL
+ initializer */
+ {
+ ES3_OR_NEWER("[]", (yylsp[-2]), "first-class arrays (array initializer)");
+ (yyval.interm).type = (yyvsp[-4].interm.type);
+ (yyval.interm).intermDeclaration = context->parseSingleArrayInitDeclaration(
+ (yyval.interm).type, (yylsp[-3]), ImmutableString((yyvsp[-3].lex).string),
+ (yylsp[-2]), *((yyvsp[-2].interm.arraySizes)), (yylsp[-1]),
+ (yyvsp[0].interm.intermTypedNode));
+ }
+ break;
+
+ case 119: /* single_declaration: fully_specified_type identifier EQUAL initializer */
+ {
+ (yyval.interm).type = (yyvsp[-3].interm.type);
+ (yyval.interm).intermDeclaration = context->parseSingleInitDeclaration(
+ (yyval.interm).type, (yylsp[-2]), ImmutableString((yyvsp[-2].lex).string),
+ (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ }
+ break;
+
+ case 120: /* fully_specified_type: type_specifier */
+ {
+ context->addFullySpecifiedType(&(yyvsp[0].interm.type));
+ (yyval.interm.type) = (yyvsp[0].interm.type);
+ }
+ break;
+
+ case 121: /* fully_specified_type: type_qualifier type_specifier */
+ {
+ (yyval.interm.type) = context->addFullySpecifiedType(
+ *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.type));
+ }
+ break;
+
+ case 122: /* interpolation_qualifier: SMOOTH */
+ {
+ (yyval.interm.qualifier) = EvqSmooth;
+ }
+ break;
+
+ case 123: /* interpolation_qualifier: FLAT */
+ {
+ (yyval.interm.qualifier) = EvqFlat;
+ }
+ break;
+
+ case 124: /* interpolation_qualifier: NOPERSPECTIVE */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]),
+ TExtension::NV_shader_noperspective_interpolation))
+ {
+ context->error((yylsp[0]), "unsupported interpolation qualifier", "noperspective");
+ }
+ (yyval.interm.qualifier) = EvqNoPerspective;
+ }
+ break;
+
+ case 125: /* type_qualifier: single_type_qualifier */
+ {
+ (yyval.interm.typeQualifierBuilder) = context->createTypeQualifierBuilder((yylsp[0]));
+ (yyval.interm.typeQualifierBuilder)
+ ->appendQualifier((yyvsp[0].interm.qualifierWrapper));
+ }
+ break;
+
+ case 126: /* type_qualifier: type_qualifier single_type_qualifier */
+ {
+ (yyval.interm.typeQualifierBuilder) = (yyvsp[-1].interm.typeQualifierBuilder);
+ (yyval.interm.typeQualifierBuilder)
+ ->appendQualifier((yyvsp[0].interm.qualifierWrapper));
+ }
+ break;
+
+ case 127: /* invariant_qualifier: INVARIANT */
+ {
+ // empty
+ }
+ break;
+
+ case 128: /* precise_qualifier: PRECISE */
+ {
+ context->markShaderHasPrecise();
+ }
+ break;
+
+ case 129: /* single_type_qualifier: storage_qualifier */
+ {
+ context->checkLocalVariableConstStorageQualifier(*(yyvsp[0].interm.qualifierWrapper));
+ (yyval.interm.qualifierWrapper) = (yyvsp[0].interm.qualifierWrapper);
+ }
+ break;
+
+ case 130: /* single_type_qualifier: layout_qualifier */
+ {
+ context->checkIsAtGlobalLevel((yylsp[0]), "layout");
+ (yyval.interm.qualifierWrapper) =
+ new TLayoutQualifierWrapper((yyvsp[0].interm.layoutQualifier), (yylsp[0]));
+ }
+ break;
+
+ case 131: /* single_type_qualifier: precision_qualifier */
+ {
+ (yyval.interm.qualifierWrapper) =
+ new TPrecisionQualifierWrapper((yyvsp[0].interm.precision), (yylsp[0]));
+ }
+ break;
+
+ case 132: /* single_type_qualifier: interpolation_qualifier */
+ {
+ (yyval.interm.qualifierWrapper) =
+ new TInterpolationQualifierWrapper((yyvsp[0].interm.qualifier), (yylsp[0]));
+ }
+ break;
+
+ case 133: /* single_type_qualifier: invariant_qualifier */
+ {
+ context->checkIsAtGlobalLevel((yylsp[0]), "invariant");
+ (yyval.interm.qualifierWrapper) = new TInvariantQualifierWrapper((yylsp[0]));
+ }
+ break;
+
+ case 134: /* single_type_qualifier: precise_qualifier */
+ {
+ (yyval.interm.qualifierWrapper) = new TPreciseQualifierWrapper((yylsp[0]));
+ }
+ break;
+
+ case 135: /* storage_qualifier: ATTRIBUTE */
+ {
+ VERTEX_ONLY("attribute", (yylsp[0]));
+ ES2_ONLY("attribute", (yylsp[0]));
+ (yyval.interm.qualifierWrapper) =
+ context->parseGlobalStorageQualifier(EvqAttribute, (yylsp[0]));
+ }
+ break;
+
+ case 136: /* storage_qualifier: VARYING */
+ {
+ ES2_ONLY("varying", (yylsp[0]));
+ (yyval.interm.qualifierWrapper) = context->parseVaryingQualifier((yylsp[0]));
+ }
+ break;
+
+ case 137: /* storage_qualifier: CONST_QUAL */
+ {
+ (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqConst, (yylsp[0]));
+ }
+ break;
+
+ case 138: /* storage_qualifier: IN_QUAL */
+ {
+ (yyval.interm.qualifierWrapper) = context->parseInQualifier((yylsp[0]));
+ }
+ break;
+
+ case 139: /* storage_qualifier: OUT_QUAL */
+ {
+ (yyval.interm.qualifierWrapper) = context->parseOutQualifier((yylsp[0]));
+ }
+ break;
+
+ case 140: /* storage_qualifier: INOUT_QUAL */
+ {
+ (yyval.interm.qualifierWrapper) = context->parseInOutQualifier((yylsp[0]));
+ }
+ break;
+
+ case 141: /* storage_qualifier: CENTROID */
+ {
+ ES3_OR_NEWER("centroid", (yylsp[0]), "storage qualifier");
+ (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqCentroid, (yylsp[0]));
+ }
+ break;
+
+ case 142: /* storage_qualifier: PATCH */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_tessellation_shader))
+ {
+ context->error((yylsp[0]), "unsupported storage qualifier", "patch");
+ }
+ (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqPatch, (yylsp[0]));
+ }
+ break;
+
+ case 143: /* storage_qualifier: UNIFORM */
+ {
+ (yyval.interm.qualifierWrapper) =
+ context->parseGlobalStorageQualifier(EvqUniform, (yylsp[0]));
+ }
+ break;
+
+ case 144: /* storage_qualifier: BUFFER */
+ {
+ ES3_1_OR_NEWER("buffer", (yylsp[0]), "storage qualifier");
+ (yyval.interm.qualifierWrapper) =
+ context->parseGlobalStorageQualifier(EvqBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 145: /* storage_qualifier: READONLY */
+ {
+ (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqReadOnly, (yylsp[0]));
+ }
+ break;
+
+ case 146: /* storage_qualifier: WRITEONLY */
+ {
+ (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqWriteOnly, (yylsp[0]));
+ }
+ break;
+
+ case 147: /* storage_qualifier: COHERENT */
+ {
+ (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqCoherent, (yylsp[0]));
+ }
+ break;
+
+ case 148: /* storage_qualifier: RESTRICT */
+ {
+ (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqRestrict, (yylsp[0]));
+ }
+ break;
+
+ case 149: /* storage_qualifier: VOLATILE */
+ {
+ (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqVolatile, (yylsp[0]));
+ }
+ break;
+
+ case 150: /* storage_qualifier: SHARED */
+ {
+ COMPUTE_ONLY("shared", (yylsp[0]));
+ (yyval.interm.qualifierWrapper) =
+ context->parseGlobalStorageQualifier(EvqShared, (yylsp[0]));
+ }
+ break;
+
+ case 151: /* storage_qualifier: SAMPLE */
+ {
+ ES3_OR_NEWER("sample", (yylsp[0]), "storage qualifier");
+ (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqSample, (yylsp[0]));
+ }
+ break;
+
+ case 152: /* type_specifier: type_specifier_no_prec */
+ {
+ (yyval.interm.type) = (yyvsp[0].interm.type);
+ (yyval.interm.type).precision =
+ context->symbolTable.getDefaultPrecision((yyvsp[0].interm.type).getBasicType());
+ }
+ break;
+
+ case 153: /* precision_qualifier: HIGH_PRECISION */
+ {
+ (yyval.interm.precision) = EbpHigh;
+ }
+ break;
+
+ case 154: /* precision_qualifier: MEDIUM_PRECISION */
+ {
+ (yyval.interm.precision) = EbpMedium;
+ }
+ break;
+
+ case 155: /* precision_qualifier: LOW_PRECISION */
+ {
+ (yyval.interm.precision) = EbpLow;
+ }
+ break;
+
+ case 156: /* layout_qualifier: LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN */
+ {
+ context->checkCanUseLayoutQualifier((yylsp[-3]));
+ (yyval.interm.layoutQualifier) = (yyvsp[-1].interm.layoutQualifier);
+ }
+ break;
+
+ case 157: /* layout_qualifier_id_list: layout_qualifier_id */
+ {
+ (yyval.interm.layoutQualifier) = (yyvsp[0].interm.layoutQualifier);
+ }
+ break;
+
+ case 158: /* layout_qualifier_id_list: layout_qualifier_id_list COMMA layout_qualifier_id */
+ {
+ (yyval.interm.layoutQualifier) = context->joinLayoutQualifiers(
+ (yyvsp[-2].interm.layoutQualifier), (yyvsp[0].interm.layoutQualifier), (yylsp[0]));
+ }
+ break;
+
+ case 159: /* layout_qualifier_id: IDENTIFIER */
+ {
+ (yyval.interm.layoutQualifier) =
+ context->parseLayoutQualifier(ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
+ }
+ break;
+
+ case 160: /* layout_qualifier_id: IDENTIFIER EQUAL INTCONSTANT */
+ {
+ (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(
+ ImmutableString((yyvsp[-2].lex).string), (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
+ }
+ break;
+
+ case 161: /* layout_qualifier_id: IDENTIFIER EQUAL UINTCONSTANT */
+ {
+ (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(
+ ImmutableString((yyvsp[-2].lex).string), (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
+ }
+ break;
+
+ case 162: /* layout_qualifier_id: SHARED */
+ {
+ (yyval.interm.layoutQualifier) =
+ context->parseLayoutQualifier(ImmutableString("shared"), (yylsp[0]));
+ }
+ break;
+
+ case 163: /* type_specifier_no_prec: type_specifier_nonarray */
+ {
+ (yyval.interm.type)
+ .initialize((yyvsp[0].interm.typeSpecifierNonArray),
+ (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
+ }
+ break;
+
+ case 164: /* type_specifier_no_prec: type_specifier_nonarray array_specifier */
+ {
+ (yyval.interm.type)
+ .initialize((yyvsp[-1].interm.typeSpecifierNonArray),
+ (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
+ (yyval.interm.type).setArraySizes((yyvsp[0].interm.arraySizes));
+ }
+ break;
+
+ case 165: /* array_specifier: LEFT_BRACKET RIGHT_BRACKET */
+ {
+ ES3_OR_NEWER("[]", (yylsp[-1]), "implicitly sized array");
+ (yyval.interm.arraySizes) = new TVector<unsigned int>();
+ (yyval.interm.arraySizes)->push_back(0u);
+ }
+ break;
+
+ case 166: /* array_specifier: LEFT_BRACKET constant_expression RIGHT_BRACKET */
+ {
+ (yyval.interm.arraySizes) = new TVector<unsigned int>();
+ unsigned int size =
+ context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
+ // Make the type an array even if size check failed.
+ // This ensures useless error messages regarding a variable's non-arrayness won't
+ // follow.
+ (yyval.interm.arraySizes)->push_back(size);
+ }
+ break;
+
+ case 167: /* array_specifier: array_specifier LEFT_BRACKET RIGHT_BRACKET */
+ {
+ ES3_1_OR_NEWER("[]", (yylsp[-1]), "arrays of arrays");
+ (yyval.interm.arraySizes) = (yyvsp[-2].interm.arraySizes);
+ (yyval.interm.arraySizes)->insert((yyval.interm.arraySizes)->begin(), 0u);
+ }
+ break;
+
+ case 168: /* array_specifier: array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET
+ */
+ {
+ ES3_1_OR_NEWER("[]", (yylsp[-2]), "arrays of arrays");
+ (yyval.interm.arraySizes) = (yyvsp[-3].interm.arraySizes);
+ unsigned int size =
+ context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
+ // Make the type an array even if size check failed.
+ // This ensures useless error messages regarding a variable's non-arrayness won't
+ // follow.
+ (yyval.interm.arraySizes)->insert((yyval.interm.arraySizes)->begin(), size);
+ }
+ break;
+
+ case 169: /* type_specifier_nonarray: VOID_TYPE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtVoid, (yylsp[0]));
+ }
+ break;
+
+ case 170: /* type_specifier_nonarray: FLOAT_TYPE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ }
+ break;
+
+ case 171: /* type_specifier_nonarray: INT_TYPE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
+ }
+ break;
+
+ case 172: /* type_specifier_nonarray: UINT_TYPE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
+ }
+ break;
+
+ case 173: /* type_specifier_nonarray: BOOL_TYPE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
+ }
+ break;
+
+ case 174: /* type_specifier_nonarray: VEC2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ }
+ break;
+
+ case 175: /* type_specifier_nonarray: VEC3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ }
+ break;
+
+ case 176: /* type_specifier_nonarray: VEC4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ }
+ break;
+
+ case 177: /* type_specifier_nonarray: BVEC2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ }
+ break;
+
+ case 178: /* type_specifier_nonarray: BVEC3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ }
+ break;
+
+ case 179: /* type_specifier_nonarray: BVEC4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ }
+ break;
+
+ case 180: /* type_specifier_nonarray: IVEC2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ }
+ break;
+
+ case 181: /* type_specifier_nonarray: IVEC3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ }
+ break;
+
+ case 182: /* type_specifier_nonarray: IVEC4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ }
+ break;
+
+ case 183: /* type_specifier_nonarray: UVEC2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ }
+ break;
+
+ case 184: /* type_specifier_nonarray: UVEC3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ }
+ break;
+
+ case 185: /* type_specifier_nonarray: UVEC4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ }
+ break;
+
+ case 186: /* type_specifier_nonarray: MATRIX2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(2, 2);
+ }
+ break;
+
+ case 187: /* type_specifier_nonarray: MATRIX3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(3, 3);
+ }
+ break;
+
+ case 188: /* type_specifier_nonarray: MATRIX4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(4, 4);
+ }
+ break;
+
+ case 189: /* type_specifier_nonarray: MATRIX2x3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(2, 3);
+ }
+ break;
+
+ case 190: /* type_specifier_nonarray: MATRIX3x2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(3, 2);
+ }
+ break;
+
+ case 191: /* type_specifier_nonarray: MATRIX2x4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(2, 4);
+ }
+ break;
+
+ case 192: /* type_specifier_nonarray: MATRIX4x2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(4, 2);
+ }
+ break;
+
+ case 193: /* type_specifier_nonarray: MATRIX3x4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(3, 4);
+ }
+ break;
+
+ case 194: /* type_specifier_nonarray: MATRIX4x3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(4, 3);
+ }
+ break;
+
+ case 195: /* type_specifier_nonarray: YUVCSCSTANDARDEXT */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]), TExtension::EXT_YUV_target))
+ {
+ context->error((yylsp[0]), "unsupported type", "yuvCscStandardEXT");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtYuvCscStandardEXT, (yylsp[0]));
+ }
+ break;
+
+ case 196: /* type_specifier_nonarray: SAMPLER2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2D, (yylsp[0]));
+ }
+ break;
+
+ case 197: /* type_specifier_nonarray: SAMPLER3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler3D, (yylsp[0]));
+ }
+ break;
+
+ case 198: /* type_specifier_nonarray: SAMPLERCUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCube, (yylsp[0]));
+ }
+ break;
+
+ case 199: /* type_specifier_nonarray: SAMPLER2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 200: /* type_specifier_nonarray: SAMPLER2DMS */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DMS, (yylsp[0]));
+ }
+ break;
+
+ case 201: /* type_specifier_nonarray: SAMPLER2DMSARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DMSArray, (yylsp[0]));
+ }
+ break;
+
+ case 202: /* type_specifier_nonarray: SAMPLERCUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 203: /* type_specifier_nonarray: SAMPLERCUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 204: /* type_specifier_nonarray: SAMPLERBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 205: /* type_specifier_nonarray: ISAMPLER2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2D, (yylsp[0]));
+ }
+ break;
+
+ case 206: /* type_specifier_nonarray: ISAMPLER3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler3D, (yylsp[0]));
+ }
+ break;
+
+ case 207: /* type_specifier_nonarray: ISAMPLERCUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerCube, (yylsp[0]));
+ }
+ break;
+
+ case 208: /* type_specifier_nonarray: ISAMPLER2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 209: /* type_specifier_nonarray: ISAMPLER2DMS */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DMS, (yylsp[0]));
+ }
+ break;
+
+ case 210: /* type_specifier_nonarray: ISAMPLER2DMSARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DMSArray, (yylsp[0]));
+ }
+ break;
+
+ case 211: /* type_specifier_nonarray: ISAMPLERCUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__isamplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 212: /* type_specifier_nonarray: ISAMPLERCUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__isamplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 213: /* type_specifier_nonarray: ISAMPLERBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__isamplerBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 214: /* type_specifier_nonarray: USAMPLER2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2D, (yylsp[0]));
+ }
+ break;
+
+ case 215: /* type_specifier_nonarray: USAMPLER3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler3D, (yylsp[0]));
+ }
+ break;
+
+ case 216: /* type_specifier_nonarray: USAMPLERCUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerCube, (yylsp[0]));
+ }
+ break;
+
+ case 217: /* type_specifier_nonarray: USAMPLER2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 218: /* type_specifier_nonarray: USAMPLER2DMS */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DMS, (yylsp[0]));
+ }
+ break;
+
+ case 219: /* type_specifier_nonarray: USAMPLER2DMSARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DMSArray, (yylsp[0]));
+ }
+ break;
+
+ case 220: /* type_specifier_nonarray: USAMPLERCUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__usamplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 221: /* type_specifier_nonarray: USAMPLERCUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__usamplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 222: /* type_specifier_nonarray: USAMPLERBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__usamplerBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 223: /* type_specifier_nonarray: SAMPLER2DSHADOW */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DShadow, (yylsp[0]));
+ }
+ break;
+
+ case 224: /* type_specifier_nonarray: SAMPLERCUBESHADOW */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeShadow, (yylsp[0]));
+ }
+ break;
+
+ case 225: /* type_specifier_nonarray: SAMPLER2DARRAYSHADOW */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArrayShadow, (yylsp[0]));
+ }
+ break;
+
+ case 226: /* type_specifier_nonarray: SAMPLERCUBEARRAYSHADOWOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerCubeArrayShadow");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeArrayShadow, (yylsp[0]));
+ }
+ break;
+
+ case 227: /* type_specifier_nonarray: SAMPLERCUBEARRAYSHADOWEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerCubeArrayShadow");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeArrayShadow, (yylsp[0]));
+ }
+ break;
+
+ case 228: /* type_specifier_nonarray: SAMPLERVIDEOWEBGL */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]), TExtension::WEBGL_video_texture))
+ {
+ context->error((yylsp[0]), "unsupported type", "samplerVideoWEBGL");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerVideoWEBGL, (yylsp[0]));
+ }
+ break;
+
+ case 229: /* type_specifier_nonarray: SAMPLER_EXTERNAL_OES */
+ {
+ constexpr std::array<TExtension, 3u> extensions{
+ {TExtension::NV_EGL_stream_consumer_external,
+ TExtension::OES_EGL_image_external_essl3, TExtension::OES_EGL_image_external}};
+ if (!context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "samplerExternalOES");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerExternalOES, (yylsp[0]));
+ }
+ break;
+
+ case 230: /* type_specifier_nonarray: SAMPLEREXTERNAL2DY2YEXT */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]), TExtension::EXT_YUV_target))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerExternal2DY2YEXT");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerExternal2DY2YEXT, (yylsp[0]));
+ }
+ break;
+
+ case 231: /* type_specifier_nonarray: SAMPLER2DRECT */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]), TExtension::ARB_texture_rectangle))
+ {
+ context->error((yylsp[0]), "unsupported type", "sampler2DRect");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DRect, (yylsp[0]));
+ }
+ break;
+
+ case 232: /* type_specifier_nonarray: IMAGE2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImage2D, (yylsp[0]));
+ }
+ break;
+
+ case 233: /* type_specifier_nonarray: IIMAGE2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImage2D, (yylsp[0]));
+ }
+ break;
+
+ case 234: /* type_specifier_nonarray: UIMAGE2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImage2D, (yylsp[0]));
+ }
+ break;
+
+ case 235: /* type_specifier_nonarray: IMAGE3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImage3D, (yylsp[0]));
+ }
+ break;
+
+ case 236: /* type_specifier_nonarray: IIMAGE3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImage3D, (yylsp[0]));
+ }
+ break;
+
+ case 237: /* type_specifier_nonarray: UIMAGE3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImage3D, (yylsp[0]));
+ }
+ break;
+
+ case 238: /* type_specifier_nonarray: IMAGE2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImage2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 239: /* type_specifier_nonarray: IIMAGE2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImage2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 240: /* type_specifier_nonarray: UIMAGE2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImage2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 241: /* type_specifier_nonarray: IMAGECUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImageCube, (yylsp[0]));
+ }
+ break;
+
+ case 242: /* type_specifier_nonarray: IIMAGECUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImageCube, (yylsp[0]));
+ }
+ break;
+
+ case 243: /* type_specifier_nonarray: UIMAGECUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImageCube, (yylsp[0]));
+ }
+ break;
+
+ case 244: /* type_specifier_nonarray: IMAGECUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__imageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 245: /* type_specifier_nonarray: IMAGECUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__imageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 246: /* type_specifier_nonarray: IIMAGECUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__iimageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 247: /* type_specifier_nonarray: IIMAGECUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__iimageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 248: /* type_specifier_nonarray: UIMAGECUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__uimageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 249: /* type_specifier_nonarray: UIMAGECUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__uimageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 250: /* type_specifier_nonarray: IMAGEBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__imageBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImageBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 251: /* type_specifier_nonarray: IIMAGEBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__iimageBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImageBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 252: /* type_specifier_nonarray: UIMAGEBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__uimageBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImageBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 253: /* type_specifier_nonarray: ATOMICUINT */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtAtomicCounter, (yylsp[0]));
+ }
+ break;
+
+ case 254: /* type_specifier_nonarray: PIXELLOCALANGLE */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]),
+ TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ context->error((yylsp[0]), "unsupported type", "__pixelLocalANGLE");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtPixelLocalANGLE, (yylsp[0]));
+ }
+ break;
+
+ case 255: /* type_specifier_nonarray: IPIXELLOCALANGLE */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]),
+ TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ context->error((yylsp[0]), "unsupported type", "__ipixelLocalANGLE");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIPixelLocalANGLE, (yylsp[0]));
+ }
+ break;
+
+ case 256: /* type_specifier_nonarray: UPIXELLOCALANGLE */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]),
+ TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ context->error((yylsp[0]), "unsupported type", "__upixelLocalANGLE");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUPixelLocalANGLE, (yylsp[0]));
+ }
+ break;
+
+ case 257: /* type_specifier_nonarray: struct_specifier */
+ {
+ (yyval.interm.typeSpecifierNonArray) = (yyvsp[0].interm.typeSpecifierNonArray);
+ }
+ break;
+
+ case 258: /* type_specifier_nonarray: TYPE_NAME */
+ {
+ // This is for user defined type names. The lexical phase looked up the type.
+ const TStructure *structure = static_cast<const TStructure *>((yyvsp[0].lex).symbol);
+ (yyval.interm.typeSpecifierNonArray).initializeStruct(structure, false, (yylsp[0]));
+ }
+ break;
+
+ case 259: /* $@1: %empty */
+ {
+ context->enterStructDeclaration((yylsp[-1]), ImmutableString((yyvsp[-1].lex).string));
+ }
+ break;
+
+ case 260: /* struct_specifier: STRUCT identifier LEFT_BRACE $@1 struct_declaration_list
+ RIGHT_BRACE */
+ {
+ (yyval.interm.typeSpecifierNonArray) = context->addStructure(
+ (yylsp[-5]), (yylsp[-4]), ImmutableString((yyvsp[-4].lex).string),
+ (yyvsp[-1].interm.fieldList));
+ }
+ break;
+
+ case 261: /* $@2: %empty */
+ {
+ context->enterStructDeclaration((yylsp[0]), kEmptyImmutableString);
+ }
+ break;
+
+ case 262: /* struct_specifier: STRUCT LEFT_BRACE $@2 struct_declaration_list RIGHT_BRACE */
+ {
+ (yyval.interm.typeSpecifierNonArray) = context->addStructure(
+ (yylsp[-4]), (yyloc), kEmptyImmutableString, (yyvsp[-1].interm.fieldList));
+ }
+ break;
+
+ case 263: /* struct_declaration_list: struct_declaration */
+ {
+ (yyval.interm.fieldList) =
+ context->addStructFieldList((yyvsp[0].interm.fieldList), (yylsp[0]));
+ }
+ break;
+
+ case 264: /* struct_declaration_list: struct_declaration_list struct_declaration */
+ {
+ (yyval.interm.fieldList) = context->combineStructFieldLists(
+ (yyvsp[-1].interm.fieldList), (yyvsp[0].interm.fieldList), (yylsp[0]));
+ }
+ break;
+
+ case 265: /* struct_declaration: type_specifier struct_declarator_list SEMICOLON */
+ {
+ (yyval.interm.fieldList) = context->addStructDeclaratorList(
+ (yyvsp[-2].interm.type), (yyvsp[-1].interm.declaratorList));
+ }
+ break;
+
+ case 266: /* struct_declaration: type_qualifier type_specifier struct_declarator_list
+ SEMICOLON */
+ {
+ // ES3 Only, but errors should be handled elsewhere
+ (yyval.interm.fieldList) = context->addStructDeclaratorListWithQualifiers(
+ *(yyvsp[-3].interm.typeQualifierBuilder), &(yyvsp[-2].interm.type),
+ (yyvsp[-1].interm.declaratorList));
+ }
+ break;
+
+ case 267: /* struct_declarator_list: struct_declarator */
+ {
+ (yyval.interm.declaratorList) = new TDeclaratorList();
+ (yyval.interm.declaratorList)->push_back((yyvsp[0].interm.declarator));
+ }
+ break;
+
+ case 268: /* struct_declarator_list: struct_declarator_list COMMA struct_declarator */
+ {
+ (yyval.interm.declaratorList)->push_back((yyvsp[0].interm.declarator));
+ }
+ break;
+
+ case 269: /* struct_declarator: identifier */
+ {
+ (yyval.interm.declarator) =
+ context->parseStructDeclarator(ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
+ }
+ break;
+
+ case 270: /* struct_declarator: identifier array_specifier */
+ {
+ (yyval.interm.declarator) = context->parseStructArrayDeclarator(
+ ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]), (yyvsp[0].interm.arraySizes));
+ }
+ break;
+
+ case 271: /* initializer: assignment_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 272: /* declaration_statement: declaration */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 273: /* statement: compound_statement_with_scope */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock);
+ }
+ break;
+
+ case 274: /* statement: simple_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 275: /* simple_statement: declaration_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 276: /* simple_statement: expression_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 277: /* simple_statement: selection_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 278: /* simple_statement: switch_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermSwitch);
+ }
+ break;
+
+ case 279: /* simple_statement: case_label */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermCase);
+ }
+ break;
+
+ case 280: /* simple_statement: iteration_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 281: /* simple_statement: jump_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 282: /* compound_statement_with_scope: LEFT_BRACE RIGHT_BRACE */
+ {
+ (yyval.interm.intermBlock) = new TIntermBlock();
+ (yyval.interm.intermBlock)->setLine((yyloc));
+ }
+ break;
+
+ case 283: /* $@3: %empty */
+ {
+ context->symbolTable.push();
+ }
+ break;
+
+ case 284: /* $@4: %empty */
+ {
+ context->symbolTable.pop();
+ }
+ break;
+
+ case 285: /* compound_statement_with_scope: LEFT_BRACE $@3 statement_list $@4 RIGHT_BRACE */
+ {
+ (yyvsp[-2].interm.intermBlock)->setLine((yyloc));
+ (yyval.interm.intermBlock) = (yyvsp[-2].interm.intermBlock);
+ }
+ break;
+
+ case 286: /* statement_no_new_scope: compound_statement_no_new_scope */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock);
+ }
+ break;
+
+ case 287: /* statement_no_new_scope: simple_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 288: /* $@5: %empty */
+ {
+ context->symbolTable.push();
+ }
+ break;
+
+ case 289: /* statement_with_scope: $@5 compound_statement_no_new_scope */
+ {
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock);
+ }
+ break;
+
+ case 290: /* $@6: %empty */
+ {
+ context->symbolTable.push();
+ }
+ break;
+
+ case 291: /* statement_with_scope: $@6 simple_statement */
+ {
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 292: /* compound_statement_no_new_scope: LEFT_BRACE RIGHT_BRACE */
+ {
+ (yyval.interm.intermBlock) = new TIntermBlock();
+ (yyval.interm.intermBlock)->setLine((yyloc));
+ }
+ break;
+
+ case 293: /* compound_statement_no_new_scope: LEFT_BRACE statement_list RIGHT_BRACE */
+ {
+ (yyvsp[-1].interm.intermBlock)->setLine((yyloc));
+ (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
+ }
+ break;
+
+ case 294: /* statement_list: statement */
+ {
+ (yyval.interm.intermBlock) = new TIntermBlock();
+ context->appendStatement((yyval.interm.intermBlock), (yyvsp[0].interm.intermNode));
+ }
+ break;
+
+ case 295: /* statement_list: statement_list statement */
+ {
+ (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
+ context->appendStatement((yyval.interm.intermBlock), (yyvsp[0].interm.intermNode));
+ }
+ break;
+
+ case 296: /* expression_statement: SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addEmptyStatement((yyloc));
+ }
+ break;
+
+ case 297: /* expression_statement: expression SEMICOLON */
+ {
+ (yyval.interm.intermNode) = (yyvsp[-1].interm.intermTypedNode);
+ }
+ break;
+
+ case 298: /* selection_statement: IF LEFT_PAREN expression RIGHT_PAREN
+ selection_rest_statement */
+ {
+ (yyval.interm.intermNode) = context->addIfElse((yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.nodePair), (yylsp[-4]));
+ }
+ break;
+
+ case 299: /* selection_rest_statement: statement_with_scope ELSE statement_with_scope */
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode);
+ (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 300: /* selection_rest_statement: statement_with_scope */
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode);
+ (yyval.interm.nodePair).node2 = nullptr;
+ }
+ break;
+
+ case 301: /* $@7: %empty */
+ {
+ context->incrSwitchNestingLevel();
+ }
+ break;
+
+ case 302: /* switch_statement: SWITCH LEFT_PAREN expression RIGHT_PAREN $@7
+ compound_statement_with_scope */
+ {
+ (yyval.interm.intermSwitch) = context->addSwitch(
+ (yyvsp[-3].interm.intermTypedNode), (yyvsp[0].interm.intermBlock), (yylsp[-5]));
+ context->decrSwitchNestingLevel();
+ }
+ break;
+
+ case 303: /* case_label: CASE constant_expression COLON */
+ {
+ (yyval.interm.intermCase) =
+ context->addCase((yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
+ }
+ break;
+
+ case 304: /* case_label: DEFAULT COLON */
+ {
+ (yyval.interm.intermCase) = context->addDefault((yylsp[-1]));
+ }
+ break;
+
+ case 305: /* condition: expression */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermTypedNode);
+ context->checkIsScalarBool((yyvsp[0].interm.intermTypedNode)->getLine(),
+ (yyvsp[0].interm.intermTypedNode));
+ }
+ break;
+
+ case 306: /* condition: fully_specified_type identifier EQUAL initializer */
+ {
+ (yyval.interm.intermNode) = context->addConditionInitializer(
+ (yyvsp[-3].interm.type), ImmutableString((yyvsp[-2].lex).string),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-2]));
+ }
+ break;
+
+ case 307: /* $@8: %empty */
+ {
+ context->symbolTable.push();
+ context->incrLoopNestingLevel();
+ }
+ break;
+
+ case 308: /* iteration_statement: WHILE LEFT_PAREN $@8 condition RIGHT_PAREN
+ statement_no_new_scope */
+ {
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) =
+ context->addLoop(ELoopWhile, 0, (yyvsp[-2].interm.intermNode), 0,
+ (yyvsp[0].interm.intermNode), (yylsp[-5]));
+ context->decrLoopNestingLevel();
+ }
+ break;
+
+ case 309: /* $@9: %empty */
+ {
+ context->incrLoopNestingLevel();
+ }
+ break;
+
+ case 310: /* iteration_statement: DO $@9 statement_with_scope WHILE LEFT_PAREN expression
+ RIGHT_PAREN SEMICOLON */
+ {
+ (yyval.interm.intermNode) =
+ context->addLoop(ELoopDoWhile, 0, (yyvsp[-2].interm.intermTypedNode), 0,
+ (yyvsp[-5].interm.intermNode), (yylsp[-4]));
+ context->decrLoopNestingLevel();
+ }
+ break;
+
+ case 311: /* $@10: %empty */
+ {
+ context->symbolTable.push();
+ context->incrLoopNestingLevel();
+ }
+ break;
+
+ case 312: /* iteration_statement: FOR LEFT_PAREN $@10 for_init_statement for_rest_statement
+ RIGHT_PAREN statement_no_new_scope */
+ {
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) = context->addLoop(
+ ELoopFor, (yyvsp[-3].interm.intermNode), (yyvsp[-2].interm.nodePair).node1,
+ reinterpret_cast<TIntermTyped *>((yyvsp[-2].interm.nodePair).node2),
+ (yyvsp[0].interm.intermNode), (yylsp[-6]));
+ context->decrLoopNestingLevel();
+ }
+ break;
+
+ case 313: /* for_init_statement: expression_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 314: /* for_init_statement: declaration_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 315: /* conditionopt: condition */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 316: /* conditionopt: %empty */
+ {
+ (yyval.interm.intermNode) = nullptr;
+ }
+ break;
+
+ case 317: /* for_rest_statement: conditionopt SEMICOLON */
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermNode);
+ (yyval.interm.nodePair).node2 = 0;
+ }
+ break;
+
+ case 318: /* for_rest_statement: conditionopt SEMICOLON expression */
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode);
+ (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 319: /* jump_statement: CONTINUE SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addBranch(EOpContinue, (yylsp[-1]));
+ }
+ break;
+
+ case 320: /* jump_statement: BREAK SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addBranch(EOpBreak, (yylsp[-1]));
+ }
+ break;
+
+ case 321: /* jump_statement: RETURN SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addBranch(EOpReturn, (yylsp[-1]));
+ }
+ break;
+
+ case 322: /* jump_statement: RETURN expression SEMICOLON */
+ {
+ (yyval.interm.intermNode) =
+ context->addBranch(EOpReturn, (yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
+ }
+ break;
+
+ case 323: /* jump_statement: DISCARD SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addBranch(EOpKill, (yylsp[-1]));
+ }
+ break;
+
+ case 324: /* translation_unit: external_declaration */
+ {
+ (yyval.interm.intermBlock) = new TIntermBlock();
+ (yyval.interm.intermBlock)->setLine((yyloc));
+ (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+ context->setTreeRoot((yyval.interm.intermBlock));
+ }
+ break;
+
+ case 325: /* translation_unit: translation_unit external_declaration */
+ {
+ (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+ }
+ break;
+
+ case 326: /* external_declaration: function_definition */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 327: /* external_declaration: declaration */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 328: /* $@11: %empty */
+ {
+ context->parseFunctionDefinitionHeader((yylsp[0]), (yyvsp[0].interm).function,
+ &((yyvsp[0].interm).intermFunctionPrototype));
+ }
+ break;
+
+ case 329: /* function_definition: function_prototype $@11 compound_statement_no_new_scope */
+ {
+ (yyval.interm.intermNode) =
+ context->addFunctionDefinition((yyvsp[-2].interm).intermFunctionPrototype,
+ (yyvsp[0].interm.intermBlock), (yylsp[-2]));
+ }
+ break;
+
+ default:
+ break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT("-> $$ =", YY_CAST(yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
+
+ YYPOPSTACK(yylen);
+ yylen = 0;
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate =
+ (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]);
+ }
+
+ goto yynewstate;
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE(yychar);
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+ yyerror(&yylloc, context, scanner, YY_("syntax error"));
+ }
+
+ yyerror_range[1] = yylloc;
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct("Error: discarding", yytoken, &yylval, &yylloc, context, scanner);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
+ ++yynerrs;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK(yylen);
+ yylen = 0;
+ YY_STACK_PRINT(yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ /* Pop stack until we find a state that shifts the error token. */
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default(yyn))
+ {
+ yyn += YYSYMBOL_YYerror;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[1] = *yylsp;
+ yydestruct("Error: popping", YY_ACCESSING_SYMBOL(yystate), yyvsp, yylsp, context, scanner);
+ YYPOPSTACK(1);
+ yystate = *yyssp;
+ YY_STACK_PRINT(yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ yyerror_range[2] = yylloc;
+ ++yylsp;
+ YYLLOC_DEFAULT(*yylsp, yyerror_range, 2);
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT("Shifting", YY_ACCESSING_SYMBOL(yyn), yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturnlab;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturnlab;
+
+/*-----------------------------------------------------------.
+| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
+`-----------------------------------------------------------*/
+yyexhaustedlab:
+ yyerror(&yylloc, context, scanner, YY_("memory exhausted"));
+ yyresult = 2;
+ goto yyreturnlab;
+
+/*----------------------------------------------------------.
+| yyreturnlab -- parsing is finished, clean up and return. |
+`----------------------------------------------------------*/
+yyreturnlab:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE(yychar);
+ yydestruct("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc, context, scanner);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK(yylen);
+ YY_STACK_PRINT(yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct("Cleanup: popping", YY_ACCESSING_SYMBOL(+*yyssp), yyvsp, yylsp, context,
+ scanner);
+ YYPOPSTACK(1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE(yyss);
+#endif
+
+ return yyresult;
+}
+
+int glslang_parse(TParseContext *context)
+{
+ return yyparse(context, context->getScanner());
+}
diff --git a/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.h b/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.h
new file mode 100644
index 0000000000..d5a48edd40
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.h
@@ -0,0 +1,320 @@
+/* A Bison parser, made by GNU Bison 3.8.2. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
+#ifndef YY_YY_GLSLANG_TAB_AUTOGEN_H_INCLUDED
+#define YY_YY_GLSLANG_TAB_AUTOGEN_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+/* "%code requires" blocks. */
+
+#define YYLTYPE TSourceLoc
+#define YYLTYPE_IS_DECLARED 1
+#define YYLTYPE_IS_TRIVIAL 1
+
+/* Token kinds. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+enum yytokentype
+{
+ YYEMPTY = -2,
+ YYEOF = 0, /* "end of file" */
+ YYerror = 256, /* error */
+ YYUNDEF = 257, /* "invalid token" */
+ INVARIANT = 258, /* INVARIANT */
+ PRECISE = 259, /* PRECISE */
+ HIGH_PRECISION = 260, /* HIGH_PRECISION */
+ MEDIUM_PRECISION = 261, /* MEDIUM_PRECISION */
+ LOW_PRECISION = 262, /* LOW_PRECISION */
+ PRECISION = 263, /* PRECISION */
+ ATTRIBUTE = 264, /* ATTRIBUTE */
+ CONST_QUAL = 265, /* CONST_QUAL */
+ BOOL_TYPE = 266, /* BOOL_TYPE */
+ FLOAT_TYPE = 267, /* FLOAT_TYPE */
+ INT_TYPE = 268, /* INT_TYPE */
+ UINT_TYPE = 269, /* UINT_TYPE */
+ BREAK = 270, /* BREAK */
+ CONTINUE = 271, /* CONTINUE */
+ DO = 272, /* DO */
+ ELSE = 273, /* ELSE */
+ FOR = 274, /* FOR */
+ IF = 275, /* IF */
+ DISCARD = 276, /* DISCARD */
+ RETURN = 277, /* RETURN */
+ SWITCH = 278, /* SWITCH */
+ CASE = 279, /* CASE */
+ DEFAULT = 280, /* DEFAULT */
+ BVEC2 = 281, /* BVEC2 */
+ BVEC3 = 282, /* BVEC3 */
+ BVEC4 = 283, /* BVEC4 */
+ IVEC2 = 284, /* IVEC2 */
+ IVEC3 = 285, /* IVEC3 */
+ IVEC4 = 286, /* IVEC4 */
+ VEC2 = 287, /* VEC2 */
+ VEC3 = 288, /* VEC3 */
+ VEC4 = 289, /* VEC4 */
+ UVEC2 = 290, /* UVEC2 */
+ UVEC3 = 291, /* UVEC3 */
+ UVEC4 = 292, /* UVEC4 */
+ MATRIX2 = 293, /* MATRIX2 */
+ MATRIX3 = 294, /* MATRIX3 */
+ MATRIX4 = 295, /* MATRIX4 */
+ IN_QUAL = 296, /* IN_QUAL */
+ OUT_QUAL = 297, /* OUT_QUAL */
+ INOUT_QUAL = 298, /* INOUT_QUAL */
+ UNIFORM = 299, /* UNIFORM */
+ BUFFER = 300, /* BUFFER */
+ VARYING = 301, /* VARYING */
+ MATRIX2x3 = 302, /* MATRIX2x3 */
+ MATRIX3x2 = 303, /* MATRIX3x2 */
+ MATRIX2x4 = 304, /* MATRIX2x4 */
+ MATRIX4x2 = 305, /* MATRIX4x2 */
+ MATRIX3x4 = 306, /* MATRIX3x4 */
+ MATRIX4x3 = 307, /* MATRIX4x3 */
+ SAMPLE = 308, /* SAMPLE */
+ CENTROID = 309, /* CENTROID */
+ FLAT = 310, /* FLAT */
+ SMOOTH = 311, /* SMOOTH */
+ NOPERSPECTIVE = 312, /* NOPERSPECTIVE */
+ PATCH = 313, /* PATCH */
+ READONLY = 314, /* READONLY */
+ WRITEONLY = 315, /* WRITEONLY */
+ COHERENT = 316, /* COHERENT */
+ RESTRICT = 317, /* RESTRICT */
+ VOLATILE = 318, /* VOLATILE */
+ SHARED = 319, /* SHARED */
+ STRUCT = 320, /* STRUCT */
+ VOID_TYPE = 321, /* VOID_TYPE */
+ WHILE = 322, /* WHILE */
+ SAMPLER2D = 323, /* SAMPLER2D */
+ SAMPLERCUBE = 324, /* SAMPLERCUBE */
+ SAMPLER_EXTERNAL_OES = 325, /* SAMPLER_EXTERNAL_OES */
+ SAMPLER2DRECT = 326, /* SAMPLER2DRECT */
+ SAMPLER2DARRAY = 327, /* SAMPLER2DARRAY */
+ ISAMPLER2D = 328, /* ISAMPLER2D */
+ ISAMPLER3D = 329, /* ISAMPLER3D */
+ ISAMPLERCUBE = 330, /* ISAMPLERCUBE */
+ ISAMPLER2DARRAY = 331, /* ISAMPLER2DARRAY */
+ USAMPLER2D = 332, /* USAMPLER2D */
+ USAMPLER3D = 333, /* USAMPLER3D */
+ USAMPLERCUBE = 334, /* USAMPLERCUBE */
+ USAMPLER2DARRAY = 335, /* USAMPLER2DARRAY */
+ SAMPLER2DMS = 336, /* SAMPLER2DMS */
+ ISAMPLER2DMS = 337, /* ISAMPLER2DMS */
+ USAMPLER2DMS = 338, /* USAMPLER2DMS */
+ SAMPLER2DMSARRAY = 339, /* SAMPLER2DMSARRAY */
+ ISAMPLER2DMSARRAY = 340, /* ISAMPLER2DMSARRAY */
+ USAMPLER2DMSARRAY = 341, /* USAMPLER2DMSARRAY */
+ SAMPLER3D = 342, /* SAMPLER3D */
+ SAMPLER3DRECT = 343, /* SAMPLER3DRECT */
+ SAMPLER2DSHADOW = 344, /* SAMPLER2DSHADOW */
+ SAMPLERCUBESHADOW = 345, /* SAMPLERCUBESHADOW */
+ SAMPLER2DARRAYSHADOW = 346, /* SAMPLER2DARRAYSHADOW */
+ SAMPLERVIDEOWEBGL = 347, /* SAMPLERVIDEOWEBGL */
+ SAMPLERCUBEARRAYOES = 348, /* SAMPLERCUBEARRAYOES */
+ SAMPLERCUBEARRAYSHADOWOES = 349, /* SAMPLERCUBEARRAYSHADOWOES */
+ ISAMPLERCUBEARRAYOES = 350, /* ISAMPLERCUBEARRAYOES */
+ USAMPLERCUBEARRAYOES = 351, /* USAMPLERCUBEARRAYOES */
+ SAMPLERCUBEARRAYEXT = 352, /* SAMPLERCUBEARRAYEXT */
+ SAMPLERCUBEARRAYSHADOWEXT = 353, /* SAMPLERCUBEARRAYSHADOWEXT */
+ ISAMPLERCUBEARRAYEXT = 354, /* ISAMPLERCUBEARRAYEXT */
+ USAMPLERCUBEARRAYEXT = 355, /* USAMPLERCUBEARRAYEXT */
+ SAMPLERBUFFER = 356, /* SAMPLERBUFFER */
+ ISAMPLERBUFFER = 357, /* ISAMPLERBUFFER */
+ USAMPLERBUFFER = 358, /* USAMPLERBUFFER */
+ SAMPLEREXTERNAL2DY2YEXT = 359, /* SAMPLEREXTERNAL2DY2YEXT */
+ IMAGE2D = 360, /* IMAGE2D */
+ IIMAGE2D = 361, /* IIMAGE2D */
+ UIMAGE2D = 362, /* UIMAGE2D */
+ IMAGE3D = 363, /* IMAGE3D */
+ IIMAGE3D = 364, /* IIMAGE3D */
+ UIMAGE3D = 365, /* UIMAGE3D */
+ IMAGE2DARRAY = 366, /* IMAGE2DARRAY */
+ IIMAGE2DARRAY = 367, /* IIMAGE2DARRAY */
+ UIMAGE2DARRAY = 368, /* UIMAGE2DARRAY */
+ IMAGECUBE = 369, /* IMAGECUBE */
+ IIMAGECUBE = 370, /* IIMAGECUBE */
+ UIMAGECUBE = 371, /* UIMAGECUBE */
+ IMAGECUBEARRAYOES = 372, /* IMAGECUBEARRAYOES */
+ IIMAGECUBEARRAYOES = 373, /* IIMAGECUBEARRAYOES */
+ UIMAGECUBEARRAYOES = 374, /* UIMAGECUBEARRAYOES */
+ IMAGECUBEARRAYEXT = 375, /* IMAGECUBEARRAYEXT */
+ IIMAGECUBEARRAYEXT = 376, /* IIMAGECUBEARRAYEXT */
+ UIMAGECUBEARRAYEXT = 377, /* UIMAGECUBEARRAYEXT */
+ IMAGEBUFFER = 378, /* IMAGEBUFFER */
+ IIMAGEBUFFER = 379, /* IIMAGEBUFFER */
+ UIMAGEBUFFER = 380, /* UIMAGEBUFFER */
+ ATOMICUINT = 381, /* ATOMICUINT */
+ PIXELLOCALANGLE = 382, /* PIXELLOCALANGLE */
+ IPIXELLOCALANGLE = 383, /* IPIXELLOCALANGLE */
+ UPIXELLOCALANGLE = 384, /* UPIXELLOCALANGLE */
+ LAYOUT = 385, /* LAYOUT */
+ YUVCSCSTANDARDEXT = 386, /* YUVCSCSTANDARDEXT */
+ YUVCSCSTANDARDEXTCONSTANT = 387, /* YUVCSCSTANDARDEXTCONSTANT */
+ IDENTIFIER = 388, /* IDENTIFIER */
+ TYPE_NAME = 389, /* TYPE_NAME */
+ FLOATCONSTANT = 390, /* FLOATCONSTANT */
+ INTCONSTANT = 391, /* INTCONSTANT */
+ UINTCONSTANT = 392, /* UINTCONSTANT */
+ BOOLCONSTANT = 393, /* BOOLCONSTANT */
+ FIELD_SELECTION = 394, /* FIELD_SELECTION */
+ LEFT_OP = 395, /* LEFT_OP */
+ RIGHT_OP = 396, /* RIGHT_OP */
+ INC_OP = 397, /* INC_OP */
+ DEC_OP = 398, /* DEC_OP */
+ LE_OP = 399, /* LE_OP */
+ GE_OP = 400, /* GE_OP */
+ EQ_OP = 401, /* EQ_OP */
+ NE_OP = 402, /* NE_OP */
+ AND_OP = 403, /* AND_OP */
+ OR_OP = 404, /* OR_OP */
+ XOR_OP = 405, /* XOR_OP */
+ MUL_ASSIGN = 406, /* MUL_ASSIGN */
+ DIV_ASSIGN = 407, /* DIV_ASSIGN */
+ ADD_ASSIGN = 408, /* ADD_ASSIGN */
+ MOD_ASSIGN = 409, /* MOD_ASSIGN */
+ LEFT_ASSIGN = 410, /* LEFT_ASSIGN */
+ RIGHT_ASSIGN = 411, /* RIGHT_ASSIGN */
+ AND_ASSIGN = 412, /* AND_ASSIGN */
+ XOR_ASSIGN = 413, /* XOR_ASSIGN */
+ OR_ASSIGN = 414, /* OR_ASSIGN */
+ SUB_ASSIGN = 415, /* SUB_ASSIGN */
+ LEFT_PAREN = 416, /* LEFT_PAREN */
+ RIGHT_PAREN = 417, /* RIGHT_PAREN */
+ LEFT_BRACKET = 418, /* LEFT_BRACKET */
+ RIGHT_BRACKET = 419, /* RIGHT_BRACKET */
+ LEFT_BRACE = 420, /* LEFT_BRACE */
+ RIGHT_BRACE = 421, /* RIGHT_BRACE */
+ DOT = 422, /* DOT */
+ COMMA = 423, /* COMMA */
+ COLON = 424, /* COLON */
+ EQUAL = 425, /* EQUAL */
+ SEMICOLON = 426, /* SEMICOLON */
+ BANG = 427, /* BANG */
+ DASH = 428, /* DASH */
+ TILDE = 429, /* TILDE */
+ PLUS = 430, /* PLUS */
+ STAR = 431, /* STAR */
+ SLASH = 432, /* SLASH */
+ PERCENT = 433, /* PERCENT */
+ LEFT_ANGLE = 434, /* LEFT_ANGLE */
+ RIGHT_ANGLE = 435, /* RIGHT_ANGLE */
+ VERTICAL_BAR = 436, /* VERTICAL_BAR */
+ CARET = 437, /* CARET */
+ AMPERSAND = 438, /* AMPERSAND */
+ QUESTION = 439 /* QUESTION */
+};
+typedef enum yytokentype yytoken_kind_t;
+#endif
+
+/* Value type. */
+#if !defined YYSTYPE && !defined YYSTYPE_IS_DECLARED
+union YYSTYPE
+{
+
+ struct
+ {
+ union
+ {
+ const char *string; // pool allocated.
+ float f;
+ int i;
+ unsigned int u;
+ bool b;
+ };
+ const TSymbol *symbol;
+ } lex;
+ struct
+ {
+ TOperator op;
+ union
+ {
+ TIntermNode *intermNode;
+ TIntermNodePair nodePair;
+ TIntermTyped *intermTypedNode;
+ TIntermAggregate *intermAggregate;
+ TIntermBlock *intermBlock;
+ TIntermDeclaration *intermDeclaration;
+ TIntermFunctionPrototype *intermFunctionPrototype;
+ TIntermSwitch *intermSwitch;
+ TIntermCase *intermCase;
+ };
+ union
+ {
+ TVector<unsigned int> *arraySizes;
+ TTypeSpecifierNonArray typeSpecifierNonArray;
+ TPublicType type;
+ TPrecision precision;
+ TLayoutQualifier layoutQualifier;
+ TQualifier qualifier;
+ TFunction *function;
+ TFunctionLookup *functionLookup;
+ TParameter param;
+ TDeclarator *declarator;
+ TDeclaratorList *declaratorList;
+ TFieldList *fieldList;
+ TQualifierWrapperBase *qualifierWrapper;
+ TTypeQualifierBuilder *typeQualifierBuilder;
+ };
+ } interm;
+};
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+/* Location type. */
+#if !defined YYLTYPE && !defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE YYLTYPE;
+struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+};
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+int yyparse(TParseContext *context, void *scanner);
+
+#endif /* !YY_YY_GLSLANG_TAB_AUTOGEN_H_INCLUDED */
diff --git a/gfx/angle/checkout/src/compiler/translator/glslang_wrapper.h b/gfx/angle/checkout/src/compiler/translator/glslang_wrapper.h
new file mode 100644
index 0000000000..a5cd49bcbb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/glslang_wrapper.h
@@ -0,0 +1,46 @@
+//
+// Copyright 2021 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// glslang_wrapper:
+// A wrapper to compile GLSL strings to SPIR-V blobs. glslang here refers to the Khronos
+// compiler.
+//
+
+#ifndef COMPILER_TRANSLATOR_GLSLANG_WRAPPER_H_
+#define COMPILER_TRANSLATOR_GLSLANG_WRAPPER_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/PackedEnums.h"
+#include "common/spirv/spirv_types.h"
+
+#include <string>
+#include <vector>
+
+namespace sh
+{
+#if defined(ANGLE_ENABLE_SPIRV_GENERATION_THROUGH_GLSLANG)
+void GlslangInitialize();
+void GlslangFinalize();
+
+// Generate SPIR-V out of intermediate GLSL through glslang.
+[[nodiscard]] bool GlslangCompileToSpirv(const ShBuiltInResources &resources,
+ sh::GLenum shaderType,
+ const std::string &shaderSource,
+ angle::spirv::Blob *spirvBlobOut);
+#else
+ANGLE_INLINE void GlslangInitialize() {}
+ANGLE_INLINE void GlslangFinalize() {}
+ANGLE_INLINE bool GlslangCompileToSpirv(const ShBuiltInResources &resources,
+ sh::GLenum shaderType,
+ const std::string &shaderSource,
+ angle::spirv::Blob *spirvBlobOut)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif // defined(ANGLE_ENABLE_VULKAN) || defined(ANGLE_ENABLE_METAL)
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_GLSLANG_WRAPPER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/length_limits.h b/gfx/angle/checkout/src/compiler/translator/length_limits.h
new file mode 100644
index 0000000000..a7d95db135
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/length_limits.h
@@ -0,0 +1,26 @@
+//
+// Copyright 2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+//
+// length_limits.h
+//
+
+#ifndef COMPILER_TRANSLATOR_LENGTHLIMITS_H_
+#define COMPILER_TRANSLATOR_LENGTHLIMITS_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+// These constants are factored out from the rest of the headers to
+// make it easier to reference them from the compiler sources.
+
+namespace sh
+{
+
+size_t GetGlobalMaxTokenSize(ShShaderSpec spec);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_LENGTHLIMITS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp
new file mode 100644
index 0000000000..bd1997a21d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp
@@ -0,0 +1,136 @@
+//
+// Copyright 2021 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ClampIndirectIndices.h: Add clamp to the indirect indices used on arrays.
+//
+
+#include "compiler/translator/tree_ops/ClampIndirectIndices.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+// Traverser that finds EOpIndexIndirect nodes and applies a clamp to their right-hand side
+// expression.
+class ClampIndirectIndicesTraverser : public TIntermTraverser
+{
+ public:
+ ClampIndirectIndicesTraverser(TCompiler *compiler, TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable), mCompiler(compiler)
+ {}
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ ASSERT(visit == PreVisit);
+
+ // Only interested in EOpIndexIndirect nodes.
+ if (node->getOp() != EOpIndexIndirect)
+ {
+ return true;
+ }
+
+ // Apply the transformation to the left and right nodes
+ bool valid = ClampIndirectIndices(mCompiler, node->getLeft(), mSymbolTable);
+ ASSERT(valid);
+ valid = ClampIndirectIndices(mCompiler, node->getRight(), mSymbolTable);
+ ASSERT(valid);
+
+ // Generate clamp(right, 0, N), where N is the size of the array being indexed minus 1. If
+ // the array is runtime-sized, the length() method is called on it.
+ const TType &leftType = node->getLeft()->getType();
+ const TType &rightType = node->getRight()->getType();
+
+ // Don't clamp indirect indices on unsized arrays in buffer blocks. They are covered by the
+ // relevant robust access behavior of the backend.
+ if (leftType.isUnsizedArray())
+ {
+ return true;
+ }
+
+ // On GLSL es 100, clamp is only defined for float, so float arguments are used.
+ //
+ // However, float clamp is unconditionally emitted to workaround driver bugs with integer
+ // clamp on Qualcomm. http://crbug.com/1217167
+ //
+ // const bool useFloatClamp = mCompiler->getShaderVersion() == 100;
+ const bool useFloatClamp = true;
+
+ TIntermConstantUnion *zero = createClampValue(0, useFloatClamp);
+ TIntermTyped *max;
+
+ if (leftType.isArray())
+ {
+ max = createClampValue(static_cast<int>(leftType.getOutermostArraySize()) - 1,
+ useFloatClamp);
+ }
+ else
+ {
+ ASSERT(leftType.isVector() || leftType.isMatrix());
+ max = createClampValue(leftType.getNominalSize() - 1, useFloatClamp);
+ }
+
+ TIntermTyped *index = node->getRight();
+ // If the index node is not an int (i.e. it's a uint), or a float (if using float clamp),
+ // cast it.
+ const TBasicType requiredBasicType = useFloatClamp ? EbtFloat : EbtInt;
+ if (rightType.getBasicType() != requiredBasicType)
+ {
+ const TType *clampType = useFloatClamp ? StaticType::GetBasic<EbtFloat, EbpHigh>()
+ : StaticType::GetBasic<EbtInt, EbpHigh>();
+ TIntermSequence constructorArgs = {index};
+ index = TIntermAggregate::CreateConstructor(*clampType, &constructorArgs);
+ }
+
+ // min(gl_PointSize, maxPointSize)
+ TIntermSequence args;
+ args.push_back(index);
+ args.push_back(zero);
+ args.push_back(max);
+ TIntermTyped *clamped =
+ CreateBuiltInFunctionCallNode("clamp", &args, *mSymbolTable, useFloatClamp ? 100 : 300);
+
+ // Cast back to int if float clamp was used.
+ if (useFloatClamp)
+ {
+ TIntermSequence constructorArgs = {clamped};
+ clamped = TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtInt, EbpHigh>(),
+ &constructorArgs);
+ }
+
+ // Replace the right node (the index) with the clamped result.
+ queueReplacementWithParent(node, node->getRight(), clamped, OriginalNode::IS_DROPPED);
+
+ // Don't recurse as left and right nodes are already processed.
+ return false;
+ }
+
+ private:
+ TIntermConstantUnion *createClampValue(int value, bool useFloat)
+ {
+ if (useFloat)
+ {
+ return CreateFloatNode(static_cast<float>(value), EbpHigh);
+ }
+ return CreateIndexNode(value);
+ }
+
+ TCompiler *mCompiler;
+};
+} // anonymous namespace
+
+bool ClampIndirectIndices(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ ClampIndirectIndicesTraverser traverser(compiler, symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.h
new file mode 100644
index 0000000000..eebbab02e6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2021 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ClampIndirectIndices.h: Add clamp to the indirect indices used on arrays.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_CLAMPINDIRECTINDICES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_CLAMPINDIRECTINDICES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool ClampIndirectIndices(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_CLAMPINDIRECTINDICES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp
new file mode 100644
index 0000000000..db006989e9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp
@@ -0,0 +1,52 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ClampPointSize.cpp: Limit the value that is written to gl_PointSize.
+//
+
+#include "compiler/translator/tree_ops/ClampPointSize.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/FindSymbolNode.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+namespace sh
+{
+
+bool ClampPointSize(TCompiler *compiler,
+ TIntermBlock *root,
+ float maxPointSize,
+ TSymbolTable *symbolTable)
+{
+ // Only clamp gl_PointSize if it's used in the shader.
+ const TIntermSymbol *glPointSize = FindSymbolNode(root, ImmutableString("gl_PointSize"));
+ if (glPointSize == nullptr)
+ {
+ return true;
+ }
+
+ TIntermTyped *pointSizeNode = glPointSize->deepCopy();
+
+ TConstantUnion *maxPointSizeConstant = new TConstantUnion();
+ maxPointSizeConstant->setFConst(maxPointSize);
+ TIntermConstantUnion *maxPointSizeNode =
+ new TIntermConstantUnion(maxPointSizeConstant, TType(EbtFloat, EbpHigh, EvqConst));
+
+ // min(gl_PointSize, maxPointSize)
+ TIntermSequence minArguments;
+ minArguments.push_back(pointSizeNode->deepCopy());
+ minArguments.push_back(maxPointSizeNode);
+ TIntermTyped *clampedPointSize =
+ CreateBuiltInFunctionCallNode("min", &minArguments, *symbolTable, 100);
+
+ // gl_PointSize = min(gl_PointSize, maxPointSize)
+ TIntermBinary *assignPointSize = new TIntermBinary(EOpAssign, pointSizeNode, clampedPointSize);
+
+ return RunAtTheEndOfShader(compiler, root, assignPointSize, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.h
new file mode 100644
index 0000000000..c42f32bde2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ClampPointSize.h: Limit the value that is written to gl_PointSize.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_CLAMPPOINTSIZE_H_
+#define COMPILER_TRANSLATOR_TREEOPS_CLAMPPOINTSIZE_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool ClampPointSize(TCompiler *compiler,
+ TIntermBlock *root,
+ float maxPointSize,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_CLAMPPOINTSIZE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.cpp
new file mode 100644
index 0000000000..5c45e1fb59
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.cpp
@@ -0,0 +1,335 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/FindFunction.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermRebuild.h"
+
+using namespace sh;
+
+namespace
+{
+
+void AppendMatrixElementArgument(TIntermSymbol *parameter,
+ int colIndex,
+ int rowIndex,
+ TIntermSequence *returnCtorArgs)
+{
+ TIntermBinary *matColN =
+ new TIntermBinary(EOpIndexDirect, parameter->deepCopy(), CreateIndexNode(colIndex));
+ TIntermSwizzle *matElem = new TIntermSwizzle(matColN, {rowIndex});
+ returnCtorArgs->push_back(matElem);
+}
+
+// Adds the argument to sequence for a scalar constructor.
+// Given scalar(scalarA) appends scalarA
+// Given scalar(vecA) appends vecA.x
+// Given scalar(matA) appends matA[0].x
+void AppendScalarFromNonScalarArguments(TFunction &function, TIntermSequence *returnCtorArgs)
+{
+ const TVariable *var = function.getParam(0);
+ TIntermSymbol *arg0 = new TIntermSymbol(var);
+
+ const TType &type = arg0->getType();
+
+ if (type.isScalar())
+ {
+ returnCtorArgs->push_back(arg0);
+ }
+ else if (type.isVector())
+ {
+ TIntermSwizzle *vecX = new TIntermSwizzle(arg0, {0});
+ returnCtorArgs->push_back(vecX);
+ }
+ else if (type.isMatrix())
+ {
+ AppendMatrixElementArgument(arg0, 0, 0, returnCtorArgs);
+ }
+}
+
+// Adds the arguments to sequence for a vector constructor from a scalar.
+// Given vecN(scalarA) appends scalarA, scalarA, ... n times
+void AppendVectorFromScalarArgument(const TType &type,
+ TFunction &function,
+ TIntermSequence *returnCtorArgs)
+{
+ const uint8_t vectorSize = type.getNominalSize();
+ const TVariable *var = function.getParam(0);
+ TIntermSymbol *v = new TIntermSymbol(var);
+ for (uint8_t i = 0; i < vectorSize; ++i)
+ {
+ returnCtorArgs->push_back(v->deepCopy());
+ }
+}
+
+// Adds the arguments to sequence for a vector or matrix constructor from the available arguments
+// applying arguments in order until the requested number of values have been extracted from the
+// given arguments or until there are no more arguments.
+void AppendValuesFromMultipleArguments(int numValuesNeeded,
+ TFunction &function,
+ TIntermSequence *returnCtorArgs)
+{
+ size_t numParameters = function.getParamCount();
+ size_t paramIndex = 0;
+ uint8_t colIndex = 0;
+ uint8_t rowIndex = 0;
+
+ for (int i = 0; i < numValuesNeeded && paramIndex < numParameters; ++i)
+ {
+ const TVariable *p = function.getParam(paramIndex);
+ TIntermSymbol *parameter = new TIntermSymbol(p);
+ if (parameter->isScalar())
+ {
+ returnCtorArgs->push_back(parameter);
+ ++paramIndex;
+ }
+ else if (parameter->isVector())
+ {
+ TIntermSwizzle *vecS = new TIntermSwizzle(parameter->deepCopy(), {rowIndex++});
+ returnCtorArgs->push_back(vecS);
+ if (rowIndex == parameter->getNominalSize())
+ {
+ ++paramIndex;
+ rowIndex = 0;
+ }
+ }
+ else if (parameter->isMatrix())
+ {
+ AppendMatrixElementArgument(parameter, colIndex, rowIndex++, returnCtorArgs);
+ if (rowIndex == parameter->getSecondarySize())
+ {
+ rowIndex = 0;
+ ++colIndex;
+ if (colIndex == parameter->getNominalSize())
+ {
+ colIndex = 0;
+ ++paramIndex;
+ }
+ }
+ }
+ }
+}
+
+// Adds the arguments for a matrix constructor from a scalar
+// putting the scalar along the diagonal and 0 everywhere else.
+void AppendMatrixFromScalarArgument(const TType &type,
+ TFunction &function,
+ TIntermSequence *returnCtorArgs)
+{
+ const TVariable *var = function.getParam(0);
+ TIntermSymbol *v = new TIntermSymbol(var);
+ const uint8_t numCols = type.getNominalSize();
+ const uint8_t numRows = type.getSecondarySize();
+ for (uint8_t col = 0; col < numCols; ++col)
+ {
+ for (uint8_t row = 0; row < numRows; ++row)
+ {
+ if (col == row)
+ {
+ returnCtorArgs->push_back(v->deepCopy());
+ }
+ else
+ {
+ returnCtorArgs->push_back(CreateFloatNode(0.0f, sh::EbpUndefined));
+ }
+ }
+ }
+}
+
+// Add the argument for a matrix constructor from a matrix
+// copying elements from the same column/row and otherwise
+// initialize to the identity matrix.
+void AppendMatrixFromMatrixArgument(const TType &type,
+ TFunction &function,
+ TIntermSequence *returnCtorArgs)
+{
+ const TVariable *var = function.getParam(0);
+ TIntermSymbol *v = new TIntermSymbol(var);
+ const uint8_t dstCols = type.getNominalSize();
+ const uint8_t dstRows = type.getSecondarySize();
+ const uint8_t srcCols = v->getNominalSize();
+ const uint8_t srcRows = v->getSecondarySize();
+ for (uint8_t dstCol = 0; dstCol < dstCols; ++dstCol)
+ {
+ for (uint8_t dstRow = 0; dstRow < dstRows; ++dstRow)
+ {
+ if (dstRow < srcRows && dstCol < srcCols)
+ {
+ AppendMatrixElementArgument(v, dstCol, dstRow, returnCtorArgs);
+ }
+ else
+ {
+ returnCtorArgs->push_back(
+ CreateFloatNode(dstRow == dstCol ? 1.0f : 0.0f, sh::EbpUndefined));
+ }
+ }
+ }
+}
+
+class Rebuild : public TIntermRebuild
+{
+ public:
+ explicit Rebuild(TCompiler &compiler) : TIntermRebuild(compiler, false, true) {}
+ PostResult visitAggregatePost(TIntermAggregate &node) override
+ {
+ if (!node.isConstructor())
+ {
+ return node;
+ }
+
+ TIntermSequence &arguments = *node.getSequence();
+ if (arguments.empty())
+ {
+ return node;
+ }
+
+ const TType &type = node.getType();
+ const TType &arg0Type = arguments[0]->getAsTyped()->getType();
+
+ if (!type.isScalar() && !type.isVector() && !type.isMatrix())
+ {
+ return node;
+ }
+
+ if (type.isArray())
+ {
+ return node;
+ }
+
+ // check for type_ctor(sameType)
+ // scalar(scalar) -> passthrough
+ // vecN(vecN) -> passthrough
+ // matN(matN) -> passthrough
+ if (arguments.size() == 1 && arg0Type == type)
+ {
+ return node;
+ }
+
+ // The following are simple casts:
+ //
+ // - basic(s) (where basic is int, uint, float or bool, and s is scalar).
+ // - gvecN(vN) (where the argument is a single vector with the same number of components).
+ // - matNxM(mNxM) (where the argument is a single matrix with the same dimensions). Note
+ // that
+ // matrices are always float, so there's no actual cast and this would be a no-op.
+ //
+ const bool isSingleScalarCast =
+ arguments.size() == 1 && type.isScalar() && arg0Type.isScalar();
+ const bool isSingleVectorCast = arguments.size() == 1 && type.isVector() &&
+ arg0Type.isVector() &&
+ type.getNominalSize() == arg0Type.getNominalSize();
+ const bool isSingleMatrixCast =
+ arguments.size() == 1 && type.isMatrix() && arg0Type.isMatrix() &&
+ type.getCols() == arg0Type.getCols() && type.getRows() == arg0Type.getRows();
+ if (isSingleScalarCast || isSingleVectorCast || isSingleMatrixCast)
+ {
+ return node;
+ }
+
+ // Cases we need to handle:
+ // scalar(vec)
+ // scalar(mat)
+ // vecN(scalar)
+ // vecN(vecM)
+ // vecN(a,...)
+ // matN(scalar) -> diag
+ // matN(vec) -> fail!
+ // manN(matM) -> corner + ident
+ // matN(a, ...)
+
+ // Build a function and pass all the constructor's arguments to it.
+ TIntermBlock *body = new TIntermBlock;
+ TFunction *function = new TFunction(&mSymbolTable, ImmutableString(""),
+ SymbolType::AngleInternal, &type, true);
+
+ for (size_t i = 0; i < arguments.size(); ++i)
+ {
+ TIntermTyped &arg = *arguments[i]->getAsTyped();
+ TType *argType = new TType(arg.getBasicType(), arg.getPrecision(), EvqParamIn,
+ arg.getNominalSize(), arg.getSecondarySize());
+ TVariable *var = CreateTempVariable(&mSymbolTable, argType);
+ function->addParameter(var);
+ }
+
+ // Build a return statement for the function that
+ // converts the arguments into the required type.
+ TIntermSequence *returnCtorArgs = new TIntermSequence();
+
+ if (type.isScalar())
+ {
+ AppendScalarFromNonScalarArguments(*function, returnCtorArgs);
+ }
+ else if (type.isVector())
+ {
+ if (arguments.size() == 1 && arg0Type.isScalar())
+ {
+ AppendVectorFromScalarArgument(type, *function, returnCtorArgs);
+ }
+ else
+ {
+ AppendValuesFromMultipleArguments(type.getNominalSize(), *function, returnCtorArgs);
+ }
+ }
+ else if (type.isMatrix())
+ {
+ if (arguments.size() == 1 && arg0Type.isScalar())
+ {
+ // MSL already handles this case
+ AppendMatrixFromScalarArgument(type, *function, returnCtorArgs);
+ }
+ else if (arg0Type.isMatrix())
+ {
+ AppendMatrixFromMatrixArgument(type, *function, returnCtorArgs);
+ }
+ else
+ {
+ AppendValuesFromMultipleArguments(type.getNominalSize() * type.getSecondarySize(),
+ *function, returnCtorArgs);
+ }
+ }
+
+ TIntermBranch *returnStatement =
+ new TIntermBranch(EOpReturn, TIntermAggregate::CreateConstructor(type, returnCtorArgs));
+ body->appendStatement(returnStatement);
+
+ TIntermFunctionDefinition *functionDefinition =
+ CreateInternalFunctionDefinitionNode(*function, body);
+ mFunctionDefs.push_back(functionDefinition);
+
+ TIntermTyped *functionCall = TIntermAggregate::CreateFunctionCall(*function, &arguments);
+
+ return *functionCall;
+ }
+
+ bool rewrite(TIntermBlock &root)
+ {
+ if (!rebuildInPlace(root))
+ {
+ return true;
+ }
+
+ size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(&root);
+ for (TIntermFunctionDefinition *functionDefinition : mFunctionDefs)
+ {
+ root.insertChildNodes(firstFunctionIndex, TIntermSequence({functionDefinition}));
+ }
+
+ return mCompiler.validateAST(&root);
+ }
+
+ private:
+ TVector<TIntermFunctionDefinition *> mFunctionDefs;
+};
+
+} // anonymous namespace
+
+bool sh::ConvertUnsupportedConstructorsToFunctionCalls(TCompiler &compiler, TIntermBlock &root)
+{
+ return Rebuild(compiler).rewrite(root);
+}
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.h
new file mode 100644
index 0000000000..720a02c9a6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREE_OPS_CONVERTUNSUPPORTEDCONSTRUCTORSTOFUNCTIONCALLS_H_
+#define COMPILER_TRANSLATOR_TREE_OPS_CONVERTUNSUPPORTEDCONSTRUCTORSTOFUNCTIONCALLS_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TInterBlock;
+class SymbolEnv;
+
+// Adds explicit type casts into the AST where casting is done implicitly.
+[[nodiscard]] bool ConvertUnsupportedConstructorsToFunctionCalls(TCompiler &compiler,
+ TIntermBlock &root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREE_OPS_CONVERTUNSUPPORTEDCONSTRUCTORSTOFUNCTIONCALLS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp
new file mode 100644
index 0000000000..8c2925949d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp
@@ -0,0 +1,196 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Applies the necessary AST transformations to support multiview rendering through instancing.
+// Check the header file For more information.
+//
+
+#include "compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_ops/InitializeVariables.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kViewIDVariableName("ViewID_OVR");
+constexpr const ImmutableString kInstanceIDVariableName("InstanceID");
+constexpr const ImmutableString kMultiviewBaseViewLayerIndexVariableName(
+ "multiviewBaseViewLayerIndex");
+
+// Adds the InstanceID and ViewID_OVR initializers to the end of the initializers' sequence.
+void InitializeViewIDAndInstanceID(const TVariable *viewID,
+ const TVariable *instanceID,
+ unsigned numberOfViews,
+ const TSymbolTable &symbolTable,
+ TIntermSequence *initializers)
+{
+ // Create an unsigned numberOfViews node.
+ TConstantUnion *numberOfViewsUnsignedConstant = new TConstantUnion();
+ numberOfViewsUnsignedConstant->setUConst(numberOfViews);
+ TIntermConstantUnion *numberOfViewsUint =
+ new TIntermConstantUnion(numberOfViewsUnsignedConstant, TType(EbtUInt, EbpLow, EvqConst));
+
+ // Create a uint(gl_InstanceID) node.
+ TIntermSequence glInstanceIDSymbolCastArguments;
+ glInstanceIDSymbolCastArguments.push_back(new TIntermSymbol(BuiltInVariable::gl_InstanceID()));
+ TIntermAggregate *glInstanceIDAsUint = TIntermAggregate::CreateConstructor(
+ TType(EbtUInt, EbpHigh, EvqTemporary), &glInstanceIDSymbolCastArguments);
+
+ // Create a uint(gl_InstanceID) / numberOfViews node.
+ TIntermBinary *normalizedInstanceID =
+ new TIntermBinary(EOpDiv, glInstanceIDAsUint, numberOfViewsUint);
+
+ // Create an int(uint(gl_InstanceID) / numberOfViews) node.
+ TIntermSequence normalizedInstanceIDCastArguments;
+ normalizedInstanceIDCastArguments.push_back(normalizedInstanceID);
+ TIntermAggregate *normalizedInstanceIDAsInt = TIntermAggregate::CreateConstructor(
+ TType(EbtInt, EbpHigh, EvqTemporary), &normalizedInstanceIDCastArguments);
+
+ // Create an InstanceID = int(uint(gl_InstanceID) / numberOfViews) node.
+ TIntermBinary *instanceIDInitializer =
+ new TIntermBinary(EOpAssign, new TIntermSymbol(instanceID), normalizedInstanceIDAsInt);
+ initializers->push_back(instanceIDInitializer);
+
+ // Create a uint(gl_InstanceID) % numberOfViews node.
+ TIntermBinary *normalizedViewID =
+ new TIntermBinary(EOpIMod, glInstanceIDAsUint->deepCopy(), numberOfViewsUint->deepCopy());
+
+ // Create a ViewID_OVR = uint(gl_InstanceID) % numberOfViews node.
+ TIntermBinary *viewIDInitializer =
+ new TIntermBinary(EOpAssign, new TIntermSymbol(viewID), normalizedViewID);
+ initializers->push_back(viewIDInitializer);
+}
+
+// Adds a branch to write int(ViewID_OVR) to either gl_ViewportIndex or gl_Layer. The branch is
+// added to the end of the initializers' sequence.
+void SelectViewIndexInVertexShader(const TVariable *viewID,
+ const TVariable *multiviewBaseViewLayerIndex,
+ TIntermSequence *initializers,
+ const TSymbolTable &symbolTable)
+{
+ // Create an int(ViewID_OVR) node.
+ TIntermSequence viewIDSymbolCastArguments;
+ viewIDSymbolCastArguments.push_back(new TIntermSymbol(viewID));
+ TIntermAggregate *viewIDAsInt = TIntermAggregate::CreateConstructor(
+ TType(EbtInt, EbpHigh, EvqTemporary), &viewIDSymbolCastArguments);
+
+ // Create a gl_ViewportIndex node.
+ TIntermSymbol *viewportIndexSymbol = new TIntermSymbol(BuiltInVariable::gl_ViewportIndex());
+
+ // Create a { gl_ViewportIndex = int(ViewID_OVR) } node.
+ TIntermBlock *viewportIndexInitializerInBlock = new TIntermBlock();
+ viewportIndexInitializerInBlock->appendStatement(
+ new TIntermBinary(EOpAssign, viewportIndexSymbol, viewIDAsInt));
+
+ // Create a gl_Layer node.
+ TIntermSymbol *layerSymbol = new TIntermSymbol(BuiltInVariable::gl_LayerVS());
+
+ // Create an int(ViewID_OVR) + multiviewBaseViewLayerIndex node
+ TIntermBinary *sumOfViewIDAndBaseViewIndex = new TIntermBinary(
+ EOpAdd, viewIDAsInt->deepCopy(), new TIntermSymbol(multiviewBaseViewLayerIndex));
+
+ // Create a { gl_Layer = int(ViewID_OVR) + multiviewBaseViewLayerIndex } node.
+ TIntermBlock *layerInitializerInBlock = new TIntermBlock();
+ layerInitializerInBlock->appendStatement(
+ new TIntermBinary(EOpAssign, layerSymbol, sumOfViewIDAndBaseViewIndex));
+
+ // Create a node to compare whether the base view index uniform is less than zero.
+ TIntermBinary *multiviewBaseViewLayerIndexZeroComparison =
+ new TIntermBinary(EOpLessThan, new TIntermSymbol(multiviewBaseViewLayerIndex),
+ CreateZeroNode(TType(EbtInt, EbpHigh, EvqConst)));
+
+ // Create an if-else statement to select the code path.
+ TIntermIfElse *multiviewBranch =
+ new TIntermIfElse(multiviewBaseViewLayerIndexZeroComparison,
+ viewportIndexInitializerInBlock, layerInitializerInBlock);
+
+ initializers->push_back(multiviewBranch);
+}
+
+} // namespace
+
+bool DeclareAndInitBuiltinsForInstancedMultiview(TCompiler *compiler,
+ TIntermBlock *root,
+ unsigned numberOfViews,
+ GLenum shaderType,
+ const ShCompileOptions &compileOptions,
+ ShShaderOutput shaderOutput,
+ TSymbolTable *symbolTable)
+{
+ ASSERT(shaderType == GL_VERTEX_SHADER || shaderType == GL_FRAGMENT_SHADER);
+
+ TQualifier viewIDQualifier = (shaderType == GL_VERTEX_SHADER) ? EvqFlatOut : EvqFlatIn;
+ const TVariable *viewID =
+ new TVariable(symbolTable, kViewIDVariableName,
+ new TType(EbtUInt, EbpHigh, viewIDQualifier), SymbolType::AngleInternal);
+
+ DeclareGlobalVariable(root, viewID);
+ if (!ReplaceVariable(compiler, root, BuiltInVariable::gl_ViewID_OVR(), viewID))
+ {
+ return false;
+ }
+ if (shaderType == GL_VERTEX_SHADER)
+ {
+ // Replacing gl_InstanceID with InstanceID should happen before adding the initializers of
+ // InstanceID and ViewID.
+ const TType *instanceIDVariableType = StaticType::Get<EbtInt, EbpHigh, EvqGlobal, 1, 1>();
+ const TVariable *instanceID =
+ new TVariable(symbolTable, kInstanceIDVariableName, instanceIDVariableType,
+ SymbolType::AngleInternal);
+ DeclareGlobalVariable(root, instanceID);
+ if (!ReplaceVariable(compiler, root, BuiltInVariable::gl_InstanceID(), instanceID))
+ {
+ return false;
+ }
+
+ TIntermSequence initializers;
+ InitializeViewIDAndInstanceID(viewID, instanceID, numberOfViews, *symbolTable,
+ &initializers);
+
+ // The AST transformation which adds the expression to select the viewport index should
+ // be done only for the GLSL and ESSL output.
+ const bool selectView = compileOptions.selectViewInNvGLSLVertexShader;
+ // Assert that if the view is selected in the vertex shader, then the output is
+ // either GLSL or ESSL.
+ ASSERT(!selectView || IsOutputGLSL(shaderOutput) || IsOutputESSL(shaderOutput));
+ if (selectView)
+ {
+ // Add a uniform to switch between side-by-side and layered rendering.
+ const TType *baseLayerIndexVariableType =
+ StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>();
+ const TVariable *multiviewBaseViewLayerIndex =
+ new TVariable(symbolTable, kMultiviewBaseViewLayerIndexVariableName,
+ baseLayerIndexVariableType, SymbolType::AngleInternal);
+ DeclareGlobalVariable(root, multiviewBaseViewLayerIndex);
+
+ // Setting a value to gl_ViewportIndex or gl_Layer should happen after ViewID_OVR's
+ // initialization.
+ SelectViewIndexInVertexShader(viewID, multiviewBaseViewLayerIndex, &initializers,
+ *symbolTable);
+ }
+
+ // Insert initializers at the beginning of main().
+ TIntermBlock *initializersBlock = new TIntermBlock();
+ initializersBlock->getSequence()->swap(initializers);
+ TIntermBlock *mainBody = FindMainBody(root);
+ mainBody->getSequence()->insert(mainBody->getSequence()->begin(), initializersBlock);
+ }
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h
new file mode 100644
index 0000000000..49a964d234
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h
@@ -0,0 +1,52 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Regardless of the shader type, the following AST transformations are applied:
+// - Add declaration of View_ID_OVR.
+// - Replace every occurrence of gl_ViewID_OVR with ViewID_OVR, mark ViewID_OVR as internal and
+// declare it as a flat varying.
+//
+// If the shader type is a vertex shader, the following AST transformations are applied:
+// - Replace every occurrence of gl_InstanceID with InstanceID, mark InstanceID as internal and set
+// its qualifier to EvqTemporary.
+// - Add initializers of ViewID_OVR and InstanceID to the beginning of the body of main. The pass
+// should be executed before any variables get collected so that usage of gl_InstanceID is recorded.
+// - If the output is ESSL or GLSL and the selectViewInNvGLSLVertexShader option is
+// enabled, the expression
+// "if (multiviewBaseViewLayerIndex < 0) {
+// gl_ViewportIndex = int(ViewID_OVR);
+// } else {
+// gl_Layer = int(ViewID_OVR) + multiviewBaseViewLayerIndex;
+// }"
+// is added after ViewID and InstanceID are initialized. Also, MultiviewRenderPath is added as a
+// uniform.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
+#define COMPILER_TRANSLATOR_TREEOPS_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "angle_gl.h"
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool DeclareAndInitBuiltinsForInstancedMultiview(
+ TCompiler *compiler,
+ TIntermBlock *root,
+ unsigned numberOfViews,
+ GLenum shaderType,
+ const ShCompileOptions &compileOptions,
+ ShShaderOutput shaderOutput,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp
new file mode 100644
index 0000000000..035de73431
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp
@@ -0,0 +1,180 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// DeferGlobalInitializers is an AST traverser that moves global initializers into a separate
+// function that is called in the beginning of main(). This enables initialization of globals with
+// uniforms or non-constant globals, as allowed by the WebGL spec. Some initializers referencing
+// non-constants may need to be unfolded into if statements in HLSL - this kind of steps should be
+// done after DeferGlobalInitializers is run. Note that it's important that the function definition
+// is at the end of the shader, as some globals may be declared after main().
+//
+// It can also initialize all uninitialized globals.
+//
+
+#include "compiler/translator/tree_ops/DeferGlobalInitializers.h"
+
+#include <vector>
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_ops/InitializeVariables.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kInitGlobalsString("initGlobals");
+
+void GetDeferredInitializers(TIntermDeclaration *declaration,
+ bool initializeUninitializedGlobals,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ bool forceDeferGlobalInitializers,
+ TIntermSequence *deferredInitializersOut,
+ std::vector<const TVariable *> *variablesToReplaceOut,
+ TSymbolTable *symbolTable)
+{
+ // SeparateDeclarations should have already been run.
+ ASSERT(declaration->getSequence()->size() == 1);
+
+ TIntermNode *declarator = declaration->getSequence()->back();
+ TIntermBinary *init = declarator->getAsBinaryNode();
+ if (init)
+ {
+ TIntermSymbol *symbolNode = init->getLeft()->getAsSymbolNode();
+ ASSERT(symbolNode);
+ TIntermTyped *expression = init->getRight();
+
+ if (expression->getQualifier() != EvqConst || !expression->hasConstantValue() ||
+ forceDeferGlobalInitializers)
+ {
+ // For variables which are not constant, defer their real initialization until
+ // after we initialize uniforms.
+ // Deferral is done also in any cases where the variable can not be converted to a
+ // constant union, since otherwise there's a chance that HLSL output will generate extra
+ // statements from the initializer expression.
+
+ // Change const global to a regular global if its initialization is deferred.
+ // This can happen if ANGLE has not been able to fold the constant expression used
+ // as an initializer.
+ ASSERT(symbolNode->getQualifier() == EvqConst ||
+ symbolNode->getQualifier() == EvqGlobal);
+ if (symbolNode->getQualifier() == EvqConst)
+ {
+ variablesToReplaceOut->push_back(&symbolNode->variable());
+ }
+
+ TIntermBinary *deferredInit =
+ new TIntermBinary(EOpAssign, symbolNode->deepCopy(), init->getRight());
+ deferredInitializersOut->push_back(deferredInit);
+
+ // Remove the initializer from the global scope and just declare the global instead.
+ declaration->replaceChildNode(init, symbolNode);
+ }
+ }
+ else if (initializeUninitializedGlobals)
+ {
+ TIntermSymbol *symbolNode = declarator->getAsSymbolNode();
+ ASSERT(symbolNode);
+
+ // Ignore ANGLE internal variables and nameless declarations.
+ if (symbolNode->variable().symbolType() == SymbolType::AngleInternal ||
+ symbolNode->variable().symbolType() == SymbolType::Empty)
+ return;
+
+ if (symbolNode->getQualifier() == EvqGlobal)
+ {
+ TIntermSequence initCode;
+ CreateInitCode(symbolNode, canUseLoopsToInitialize, highPrecisionSupported, &initCode,
+ symbolTable);
+ deferredInitializersOut->insert(deferredInitializersOut->end(), initCode.begin(),
+ initCode.end());
+ }
+ }
+}
+
+void InsertInitCallToMain(TIntermBlock *root,
+ TIntermSequence *deferredInitializers,
+ TSymbolTable *symbolTable)
+{
+ TIntermBlock *initGlobalsBlock = new TIntermBlock();
+ initGlobalsBlock->getSequence()->swap(*deferredInitializers);
+
+ TFunction *initGlobalsFunction =
+ new TFunction(symbolTable, kInitGlobalsString, SymbolType::AngleInternal,
+ StaticType::GetBasic<EbtVoid, EbpUndefined>(), false);
+
+ TIntermFunctionPrototype *initGlobalsFunctionPrototype =
+ CreateInternalFunctionPrototypeNode(*initGlobalsFunction);
+ root->getSequence()->insert(root->getSequence()->begin(), initGlobalsFunctionPrototype);
+ TIntermFunctionDefinition *initGlobalsFunctionDefinition =
+ CreateInternalFunctionDefinitionNode(*initGlobalsFunction, initGlobalsBlock);
+ root->appendStatement(initGlobalsFunctionDefinition);
+
+ TIntermSequence emptySequence;
+ TIntermAggregate *initGlobalsCall =
+ TIntermAggregate::CreateFunctionCall(*initGlobalsFunction, &emptySequence);
+
+ TIntermBlock *mainBody = FindMainBody(root);
+ mainBody->getSequence()->insert(mainBody->getSequence()->begin(), initGlobalsCall);
+}
+
+} // namespace
+
+bool DeferGlobalInitializers(TCompiler *compiler,
+ TIntermBlock *root,
+ bool initializeUninitializedGlobals,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ bool forceDeferGlobalInitializers,
+ TSymbolTable *symbolTable)
+{
+ TIntermSequence deferredInitializers;
+ std::vector<const TVariable *> variablesToReplace;
+
+ // Loop over all global statements and process the declarations. This is simpler than using a
+ // traverser.
+ for (TIntermNode *statement : *root->getSequence())
+ {
+ TIntermDeclaration *declaration = statement->getAsDeclarationNode();
+ if (declaration)
+ {
+ GetDeferredInitializers(declaration, initializeUninitializedGlobals,
+ canUseLoopsToInitialize, highPrecisionSupported,
+ forceDeferGlobalInitializers, &deferredInitializers,
+ &variablesToReplace, symbolTable);
+ }
+ }
+
+ // Add the function with initialization and the call to that.
+ if (!deferredInitializers.empty())
+ {
+ InsertInitCallToMain(root, &deferredInitializers, symbolTable);
+ }
+
+ // Replace constant variables with non-constant global variables.
+ for (const TVariable *var : variablesToReplace)
+ {
+ TType *replacementType = new TType(var->getType());
+ replacementType->setQualifier(EvqGlobal);
+ TVariable *replacement =
+ new TVariable(symbolTable, var->name(), replacementType, var->symbolType());
+ if (!ReplaceVariable(compiler, root, var, replacement))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.h
new file mode 100644
index 0000000000..58a38a982b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// DeferGlobalInitializers is an AST traverser that moves global initializers into a separate
+// function that is called in the beginning of main(). This enables initialization of globals with
+// uniforms or non-constant globals, as allowed by the WebGL spec. Some initializers referencing
+// non-constants may need to be unfolded into if statements in HLSL - this kind of steps should be
+// done after DeferGlobalInitializers is run. Note that it's important that the function definition
+// is at the end of the shader, as some globals may be declared after main().
+//
+// It can also initialize all uninitialized globals.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_DEFERGLOBALINITIALIZERS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_DEFERGLOBALINITIALIZERS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool DeferGlobalInitializers(TCompiler *compiler,
+ TIntermBlock *root,
+ bool initializeUninitializedGlobals,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ bool forceDeferGlobalInitializers,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_DEFERGLOBALINITIALIZERS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
new file mode 100644
index 0000000000..25e1fde29a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
@@ -0,0 +1,142 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// gl_FragColor needs to broadcast to all color buffers in ES2 if
+// GL_EXT_draw_buffers is explicitly enabled in a fragment shader.
+//
+// We emulate this by replacing all gl_FragColor with gl_FragData[0], and in the end
+// of main() function, assigning gl_FragData[1], ..., gl_FragData[maxDrawBuffers-1]
+// with gl_FragData[0].
+//
+
+#include "compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kGlFragDataString("gl_FragData");
+
+class GLFragColorBroadcastTraverser : public TIntermTraverser
+{
+ public:
+ GLFragColorBroadcastTraverser(int maxDrawBuffers, TSymbolTable *symbolTable, int shaderVersion)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mGLFragColorUsed(false),
+ mMaxDrawBuffers(maxDrawBuffers),
+ mShaderVersion(shaderVersion)
+ {}
+
+ [[nodiscard]] bool broadcastGLFragColor(TCompiler *compiler, TIntermBlock *root);
+
+ bool isGLFragColorUsed() const { return mGLFragColorUsed; }
+
+ protected:
+ void visitSymbol(TIntermSymbol *node) override;
+
+ TIntermBinary *constructGLFragDataNode(int index) const;
+ TIntermBinary *constructGLFragDataAssignNode(int index) const;
+
+ private:
+ bool mGLFragColorUsed;
+ int mMaxDrawBuffers;
+ const int mShaderVersion;
+};
+
+TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataNode(int index) const
+{
+ TIntermSymbol *symbol =
+ ReferenceBuiltInVariable(kGlFragDataString, *mSymbolTable, mShaderVersion);
+ TIntermTyped *indexNode = CreateIndexNode(index);
+
+ TIntermBinary *binary = new TIntermBinary(EOpIndexDirect, symbol, indexNode);
+ return binary;
+}
+
+TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataAssignNode(int index) const
+{
+ TIntermTyped *fragDataIndex = constructGLFragDataNode(index);
+ TIntermTyped *fragDataZero = constructGLFragDataNode(0);
+
+ return new TIntermBinary(EOpAssign, fragDataIndex, fragDataZero);
+}
+
+void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
+{
+ if (node->variable().symbolType() == SymbolType::BuiltIn && node->getName() == "gl_FragColor")
+ {
+ queueReplacement(constructGLFragDataNode(0), OriginalNode::IS_DROPPED);
+ mGLFragColorUsed = true;
+ }
+}
+
+bool GLFragColorBroadcastTraverser::broadcastGLFragColor(TCompiler *compiler, TIntermBlock *root)
+{
+ ASSERT(mMaxDrawBuffers > 1);
+ if (!mGLFragColorUsed)
+ {
+ return true;
+ }
+
+ TIntermBlock *broadcastBlock = new TIntermBlock();
+ // Now insert statements
+ // gl_FragData[1] = gl_FragData[0];
+ // ...
+ // gl_FragData[maxDrawBuffers - 1] = gl_FragData[0];
+ for (int colorIndex = 1; colorIndex < mMaxDrawBuffers; ++colorIndex)
+ {
+ broadcastBlock->appendStatement(constructGLFragDataAssignNode(colorIndex));
+ }
+ return RunAtTheEndOfShader(compiler, root, broadcastBlock, mSymbolTable);
+}
+
+} // namespace
+
+bool EmulateGLFragColorBroadcast(TCompiler *compiler,
+ TIntermBlock *root,
+ int maxDrawBuffers,
+ std::vector<sh::ShaderVariable> *outputVariables,
+ TSymbolTable *symbolTable,
+ int shaderVersion)
+{
+ ASSERT(maxDrawBuffers > 1);
+ GLFragColorBroadcastTraverser traverser(maxDrawBuffers, symbolTable, shaderVersion);
+ root->traverse(&traverser);
+ if (traverser.isGLFragColorUsed())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ if (!traverser.broadcastGLFragColor(compiler, root))
+ {
+ return false;
+ }
+
+ for (auto &var : *outputVariables)
+ {
+ if (var.name == "gl_FragColor")
+ {
+ // TODO(zmo): Find a way to keep the original variable information.
+ var.name = "gl_FragData";
+ var.mappedName = "gl_FragData";
+ var.arraySizes.push_back(maxDrawBuffers);
+ ASSERT(var.arraySizes.size() == 1u);
+ }
+ }
+ }
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h
new file mode 100644
index 0000000000..c71ba7c2be
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h
@@ -0,0 +1,35 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Emulate gl_FragColor broadcast behaviors in ES2 where
+// GL_EXT_draw_buffers is explicitly enabled in a fragment shader.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_EMULATEGLFRAGCOLORBROADCAST_H_
+#define COMPILER_TRANSLATOR_TREEOPS_EMULATEGLFRAGCOLORBROADCAST_H_
+
+#include <vector>
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+struct ShaderVariable;
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+// Replace all gl_FragColor with gl_FragData[0], and in the end of main() function,
+// assign gl_FragData[1] ... gl_FragData[maxDrawBuffers - 1] with gl_FragData[0].
+// If gl_FragColor is in outputVariables, it is replaced by gl_FragData.
+[[nodiscard]] bool EmulateGLFragColorBroadcast(TCompiler *compiler,
+ TIntermBlock *root,
+ int maxDrawBuffers,
+ std::vector<ShaderVariable> *outputVariables,
+ TSymbolTable *symbolTable,
+ int shaderVersion);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_EMULATEGLFRAGCOLORBROADCAST_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.cpp
new file mode 100644
index 0000000000..dfa36ad145
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.cpp
@@ -0,0 +1,274 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// EmulateGLDrawID is an AST traverser to convert the gl_DrawID builtin
+// to a uniform int
+//
+// EmulateGLBaseVertex is an AST traverser to convert the gl_BaseVertex builtin
+// to a uniform int
+//
+// EmulateGLBaseInstance is an AST traverser to convert the gl_BaseInstance builtin
+// to a uniform int
+//
+
+#include "compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kEmulatedGLDrawIDName("angle_DrawID");
+
+class FindGLDrawIDTraverser : public TIntermTraverser
+{
+ public:
+ FindGLDrawIDTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
+
+ const TVariable *getGLDrawIDBuiltinVariable() { return mVariable; }
+
+ protected:
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == BuiltInVariable::gl_DrawID())
+ {
+ mVariable = &node->variable();
+ }
+ }
+
+ private:
+ const TVariable *mVariable;
+};
+
+class AddBaseVertexToGLVertexIDTraverser : public TIntermTraverser
+{
+ public:
+ AddBaseVertexToGLVertexIDTraverser() : TIntermTraverser(true, false, false) {}
+
+ protected:
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == BuiltInVariable::gl_VertexID())
+ {
+
+ TIntermSymbol *baseVertexRef = new TIntermSymbol(BuiltInVariable::gl_BaseVertex());
+
+ TIntermBinary *addBaseVertex = new TIntermBinary(EOpAdd, node, baseVertexRef);
+ queueReplacement(addBaseVertex, OriginalNode::BECOMES_CHILD);
+ }
+ }
+};
+
+constexpr const ImmutableString kEmulatedGLBaseVertexName("angle_BaseVertex");
+
+class FindGLBaseVertexTraverser : public TIntermTraverser
+{
+ public:
+ FindGLBaseVertexTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
+
+ const TVariable *getGLBaseVertexBuiltinVariable() { return mVariable; }
+
+ protected:
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == BuiltInVariable::gl_BaseVertex())
+ {
+ mVariable = &node->variable();
+ }
+ }
+
+ private:
+ const TVariable *mVariable;
+};
+
+constexpr const ImmutableString kEmulatedGLBaseInstanceName("angle_BaseInstance");
+
+class FindGLBaseInstanceTraverser : public TIntermTraverser
+{
+ public:
+ FindGLBaseInstanceTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
+
+ const TVariable *getGLBaseInstanceBuiltinVariable() { return mVariable; }
+
+ protected:
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == BuiltInVariable::gl_BaseInstance())
+ {
+ mVariable = &node->variable();
+ }
+ }
+
+ private:
+ const TVariable *mVariable;
+};
+
+} // namespace
+
+bool EmulateGLDrawID(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ std::vector<sh::ShaderVariable> *uniforms,
+ bool shouldCollect)
+{
+ FindGLDrawIDTraverser traverser;
+ root->traverse(&traverser);
+ const TVariable *builtInVariable = traverser.getGLDrawIDBuiltinVariable();
+ if (builtInVariable)
+ {
+ const TType *type = StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>();
+ const TVariable *drawID =
+ new TVariable(symbolTable, kEmulatedGLDrawIDName, type, SymbolType::AngleInternal);
+ const TIntermSymbol *drawIDSymbol = new TIntermSymbol(drawID);
+
+ // AngleInternal variables don't get collected
+ if (shouldCollect)
+ {
+ ShaderVariable uniform;
+ uniform.name = kEmulatedGLDrawIDName.data();
+ uniform.mappedName = kEmulatedGLDrawIDName.data();
+ uniform.type = GLVariableType(*type);
+ uniform.precision = GLVariablePrecision(*type);
+ uniform.staticUse = symbolTable->isStaticallyUsed(*builtInVariable);
+ uniform.active = true;
+ uniform.binding = type->getLayoutQualifier().binding;
+ uniform.location = type->getLayoutQualifier().location;
+ uniform.offset = type->getLayoutQualifier().offset;
+ uniform.rasterOrdered = type->getLayoutQualifier().rasterOrdered;
+ uniform.readonly = type->getMemoryQualifier().readonly;
+ uniform.writeonly = type->getMemoryQualifier().writeonly;
+ uniforms->push_back(uniform);
+ }
+
+ DeclareGlobalVariable(root, drawID);
+ if (!ReplaceVariableWithTyped(compiler, root, builtInVariable, drawIDSymbol))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool EmulateGLBaseVertexBaseInstance(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ std::vector<sh::ShaderVariable> *uniforms,
+ bool shouldCollect,
+ bool addBaseVertexToVertexID)
+{
+ bool addBaseVertex = false, addBaseInstance = false;
+ ShaderVariable uniformBaseVertex, uniformBaseInstance;
+
+ if (addBaseVertexToVertexID)
+ {
+ // This is a workaround for Mac AMD GPU
+ // Replace gl_VertexID with (gl_VertexID + gl_BaseVertex)
+ AddBaseVertexToGLVertexIDTraverser traverserVertexID;
+ root->traverse(&traverserVertexID);
+ if (!traverserVertexID.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+
+ FindGLBaseVertexTraverser traverserBaseVertex;
+ root->traverse(&traverserBaseVertex);
+ const TVariable *builtInVariableBaseVertex =
+ traverserBaseVertex.getGLBaseVertexBuiltinVariable();
+
+ if (builtInVariableBaseVertex)
+ {
+ const TVariable *baseVertex = BuiltInVariable::angle_BaseVertex();
+ const TType &type = baseVertex->getType();
+ const TIntermSymbol *baseVertexSymbol = new TIntermSymbol(baseVertex);
+
+ // AngleInternal variables don't get collected
+ if (shouldCollect)
+ {
+ uniformBaseVertex.name = kEmulatedGLBaseVertexName.data();
+ uniformBaseVertex.mappedName = kEmulatedGLBaseVertexName.data();
+ uniformBaseVertex.type = GLVariableType(type);
+ uniformBaseVertex.precision = GLVariablePrecision(type);
+ uniformBaseVertex.staticUse = symbolTable->isStaticallyUsed(*builtInVariableBaseVertex);
+ uniformBaseVertex.active = true;
+ uniformBaseVertex.binding = type.getLayoutQualifier().binding;
+ uniformBaseVertex.location = type.getLayoutQualifier().location;
+ uniformBaseVertex.offset = type.getLayoutQualifier().offset;
+ uniformBaseVertex.rasterOrdered = type.getLayoutQualifier().rasterOrdered;
+ uniformBaseVertex.readonly = type.getMemoryQualifier().readonly;
+ uniformBaseVertex.writeonly = type.getMemoryQualifier().writeonly;
+ addBaseVertex = true;
+ }
+
+ DeclareGlobalVariable(root, baseVertex);
+ if (!ReplaceVariableWithTyped(compiler, root, builtInVariableBaseVertex, baseVertexSymbol))
+ {
+ return false;
+ }
+ }
+
+ FindGLBaseInstanceTraverser traverserInstance;
+ root->traverse(&traverserInstance);
+ const TVariable *builtInVariableBaseInstance =
+ traverserInstance.getGLBaseInstanceBuiltinVariable();
+
+ if (builtInVariableBaseInstance)
+ {
+ const TVariable *baseInstance = BuiltInVariable::angle_BaseInstance();
+ const TType &type = baseInstance->getType();
+ const TIntermSymbol *baseInstanceSymbol = new TIntermSymbol(baseInstance);
+
+ // AngleInternal variables don't get collected
+ if (shouldCollect)
+ {
+ uniformBaseInstance.name = kEmulatedGLBaseInstanceName.data();
+ uniformBaseInstance.mappedName = kEmulatedGLBaseInstanceName.data();
+ uniformBaseInstance.type = GLVariableType(type);
+ uniformBaseInstance.precision = GLVariablePrecision(type);
+ uniformBaseInstance.staticUse =
+ symbolTable->isStaticallyUsed(*builtInVariableBaseInstance);
+ uniformBaseInstance.active = true;
+ uniformBaseInstance.binding = type.getLayoutQualifier().binding;
+ uniformBaseInstance.location = type.getLayoutQualifier().location;
+ uniformBaseInstance.offset = type.getLayoutQualifier().offset;
+ uniformBaseInstance.rasterOrdered = type.getLayoutQualifier().rasterOrdered;
+ uniformBaseInstance.readonly = type.getMemoryQualifier().readonly;
+ uniformBaseInstance.writeonly = type.getMemoryQualifier().writeonly;
+ addBaseInstance = true;
+ }
+
+ DeclareGlobalVariable(root, baseInstance);
+ if (!ReplaceVariableWithTyped(compiler, root, builtInVariableBaseInstance,
+ baseInstanceSymbol))
+ {
+ return false;
+ }
+ }
+
+ // Make sure the order in uniforms is the same as the traverse order
+ if (addBaseInstance)
+ {
+ uniforms->push_back(uniformBaseInstance);
+ }
+ if (addBaseVertex)
+ {
+ uniforms->push_back(uniformBaseVertex);
+ }
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h
new file mode 100644
index 0000000000..792a7c96b2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h
@@ -0,0 +1,47 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// EmulateGLDrawID is an AST traverser to convert the gl_DrawID builtin
+// to a uniform int
+//
+// EmulateGLBaseVertexBaseInstance is an AST traverser to convert the gl_BaseVertex and
+// gl_BaseInstance builtin to uniform ints
+//
+// EmulateGLBaseInstance is an AST traverser to convert the gl_BaseInstance builtin
+// to a uniform int
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_EMULATEMULTIDRAWSHADERBUILTINS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_EMULATEMULTIDRAWSHADERBUILTINS_H_
+
+#include <GLSLANG/ShaderLang.h>
+#include <vector>
+
+#include "common/angleutils.h"
+#include "compiler/translator/HashNames.h"
+
+namespace sh
+{
+struct ShaderVariable;
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool EmulateGLDrawID(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ std::vector<sh::ShaderVariable> *uniforms,
+ bool shouldCollect);
+
+[[nodiscard]] bool EmulateGLBaseVertexBaseInstance(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ std::vector<sh::ShaderVariable> *uniforms,
+ bool shouldCollect,
+ bool addBaseVertexToVertexID);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_EMULATEMULTIDRAWSHADERBUILTINS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp
new file mode 100644
index 0000000000..1ede8c1a46
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp
@@ -0,0 +1,120 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FoldExpressions.cpp: Fold expressions. This may fold expressions so that the qualifier of the
+// folded node differs from the qualifier of the original expression, so it needs to be done after
+// parsing and validation of qualifiers is complete. Expressions that are folded:
+// 1. Ternary ops with a constant condition.
+// 2. Sequence aka comma ops where the left side has no side effects.
+// 3. Any expressions containing any of the above.
+
+#include "compiler/translator/tree_ops/FoldExpressions.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class FoldExpressionsTraverser : public TIntermTraverser
+{
+ public:
+ FoldExpressionsTraverser(TDiagnostics *diagnostics)
+ : TIntermTraverser(true, false, false), mDiagnostics(diagnostics), mDidReplace(false)
+ {}
+
+ bool didReplace() { return mDidReplace; }
+
+ void nextIteration() { mDidReplace = false; }
+
+ protected:
+ bool visitTernary(Visit visit, TIntermTernary *node) override
+ {
+ TIntermTyped *folded = node->fold(mDiagnostics);
+ if (folded != node)
+ {
+ queueReplacement(folded, OriginalNode::IS_DROPPED);
+ mDidReplace = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ TIntermTyped *folded = node->fold(mDiagnostics);
+ if (folded != node)
+ {
+ queueReplacement(folded, OriginalNode::IS_DROPPED);
+ mDidReplace = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TIntermTyped *folded = node->fold(mDiagnostics);
+ if (folded != node)
+ {
+ queueReplacement(folded, OriginalNode::IS_DROPPED);
+ mDidReplace = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override
+ {
+ TIntermTyped *folded = node->fold(mDiagnostics);
+ if (folded != node)
+ {
+ queueReplacement(folded, OriginalNode::IS_DROPPED);
+ mDidReplace = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool visitSwizzle(Visit visit, TIntermSwizzle *node) override
+ {
+ TIntermTyped *folded = node->fold(mDiagnostics);
+ if (folded != node)
+ {
+ queueReplacement(folded, OriginalNode::IS_DROPPED);
+ mDidReplace = true;
+ return false;
+ }
+ return true;
+ }
+
+ private:
+ TDiagnostics *mDiagnostics;
+ bool mDidReplace;
+};
+
+} // anonymous namespace
+
+bool FoldExpressions(TCompiler *compiler, TIntermBlock *root, TDiagnostics *diagnostics)
+{
+ FoldExpressionsTraverser traverser(diagnostics);
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ } while (traverser.didReplace());
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.h
new file mode 100644
index 0000000000..1592444c50
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FoldExpressions.h: Fold expressions. This may fold expressions so that the qualifier of the
+// folded node differs from the qualifier of the original expression, so it needs to be done after
+// parsing and validation of qualifiers is complete. Expressions that are folded: 1. Ternary ops
+// with a constant condition.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_FOLDEXPRESSIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_FOLDEXPRESSIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TDiagnostics;
+
+[[nodiscard]] bool FoldExpressions(TCompiler *compiler,
+ TIntermBlock *root,
+ TDiagnostics *diagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_FOLDEXPRESSIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.cpp
new file mode 100644
index 0000000000..00dd0131c6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.cpp
@@ -0,0 +1,101 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_ops/ForcePrecisionQualifier.h"
+#include "angle_gl.h"
+#include "common/debug.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+class TPrecisionTraverser : public TIntermTraverser
+{
+ public:
+ TPrecisionTraverser(TSymbolTable *symbolTable);
+
+ protected:
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+
+ void overwriteVariablePrecision(TType *type) const;
+};
+
+TPrecisionTraverser::TPrecisionTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, true, true, symbolTable)
+{}
+
+void TPrecisionTraverser::overwriteVariablePrecision(TType *type) const
+{
+ if (type->getPrecision() == EbpHigh)
+ {
+ type->setPrecision(EbpMedium);
+ }
+}
+
+bool TPrecisionTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ // Variable declaration.
+ if (visit == PreVisit)
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+ TQualifier qualifier = variable->getQualifier();
+
+ // Don't modify uniform since it might be shared between vertex and fragment shader
+ if (qualifier == EvqUniform)
+ {
+ return true;
+ }
+
+ // Visit the struct.
+ if (type.isStructSpecifier())
+ {
+ const TStructure *structure = type.getStruct();
+ const TFieldList &fields = structure->fields();
+ for (size_t i = 0; i < fields.size(); ++i)
+ {
+ const TField *field = fields[i];
+ const TType *fieldType = field->type();
+ overwriteVariablePrecision((TType *)fieldType);
+ }
+ }
+ else if (type.getBasicType() == EbtInterfaceBlock)
+ {
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ const TFieldList &fields = interfaceBlock->fields();
+ for (const TField *field : fields)
+ {
+ const TType *fieldType = field->type();
+ overwriteVariablePrecision((TType *)fieldType);
+ }
+ }
+ else
+ {
+ overwriteVariablePrecision((TType *)&type);
+ }
+ }
+ return true;
+}
+} // namespace
+
+bool ForceShaderPrecisionToMediump(TIntermNode *root, TSymbolTable *symbolTable, GLenum shaderType)
+{
+ if (shaderType != GL_FRAGMENT_SHADER)
+ {
+ return true;
+ }
+
+ TPrecisionTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.h
new file mode 100644
index 0000000000..c4cde25415
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.h
@@ -0,0 +1,17 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_FORCEPRECISIONQUALIFIER_H_
+#define COMPILER_TRANSLATOR_TREEOPS_FORCEPRECISIONQUALIFIER_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+bool ForceShaderPrecisionToMediump(TIntermNode *root, TSymbolTable *symbolTable, GLenum shaderType);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_FORCEPRECISIONQUALIFIER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp
new file mode 100644
index 0000000000..789610ecc0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp
@@ -0,0 +1,359 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_ops/InitializeVariables.h"
+
+#include "angle_gl.h"
+#include "common/debug.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void AddArrayZeroInitSequence(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable);
+
+void AddStructZeroInitSequence(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable);
+
+TIntermBinary *CreateZeroInitAssignment(const TIntermTyped *initializedNode)
+{
+ TIntermTyped *zero = CreateZeroNode(initializedNode->getType());
+ return new TIntermBinary(EOpAssign, initializedNode->deepCopy(), zero);
+}
+
+void AddZeroInitSequence(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable)
+{
+ if (initializedNode->isArray())
+ {
+ AddArrayZeroInitSequence(initializedNode, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
+ }
+ else if (initializedNode->getType().isStructureContainingArrays() ||
+ initializedNode->getType().isNamelessStruct())
+ {
+ AddStructZeroInitSequence(initializedNode, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
+ }
+ else if (initializedNode->getType().isInterfaceBlock())
+ {
+ const TType &type = initializedNode->getType();
+ const TInterfaceBlock &interfaceBlock = *type.getInterfaceBlock();
+ const TFieldList &fieldList = interfaceBlock.fields();
+ for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
+ {
+ const TField &field = *fieldList[fieldIndex];
+ TIntermTyped *fieldIndexRef = CreateIndexNode(static_cast<int>(fieldIndex));
+ TIntermTyped *fieldReference =
+ new TIntermBinary(TOperator::EOpIndexDirectInterfaceBlock,
+ initializedNode->deepCopy(), fieldIndexRef);
+ TIntermTyped *fieldZero = CreateZeroNode(*field.type());
+ TIntermTyped *assignment =
+ new TIntermBinary(TOperator::EOpAssign, fieldReference, fieldZero);
+ initSequenceOut->push_back(assignment);
+ }
+ }
+ else
+ {
+ initSequenceOut->push_back(CreateZeroInitAssignment(initializedNode));
+ }
+}
+
+void AddStructZeroInitSequence(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable)
+{
+ ASSERT(initializedNode->getBasicType() == EbtStruct);
+ const TStructure *structType = initializedNode->getType().getStruct();
+ for (int i = 0; i < static_cast<int>(structType->fields().size()); ++i)
+ {
+ TIntermBinary *element = new TIntermBinary(EOpIndexDirectStruct,
+ initializedNode->deepCopy(), CreateIndexNode(i));
+ // Structs can't be defined inside structs, so the type of a struct field can't be a
+ // nameless struct.
+ ASSERT(!element->getType().isNamelessStruct());
+ AddZeroInitSequence(element, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
+ }
+}
+
+void AddArrayZeroInitStatementList(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable)
+{
+ for (unsigned int i = 0; i < initializedNode->getOutermostArraySize(); ++i)
+ {
+ TIntermBinary *element =
+ new TIntermBinary(EOpIndexDirect, initializedNode->deepCopy(), CreateIndexNode(i));
+ AddZeroInitSequence(element, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
+ }
+}
+
+void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable)
+{
+ ASSERT(initializedNode->isArray());
+ const TType *mediumpIndexType = StaticType::Get<EbtInt, EbpMedium, EvqTemporary, 1, 1>();
+ const TType *highpIndexType = StaticType::Get<EbtInt, EbpHigh, EvqTemporary, 1, 1>();
+ TVariable *indexVariable =
+ CreateTempVariable(symbolTable, highPrecisionSupported ? highpIndexType : mediumpIndexType);
+
+ TIntermSymbol *indexSymbolNode = CreateTempSymbolNode(indexVariable);
+ TIntermDeclaration *indexInit =
+ CreateTempInitDeclarationNode(indexVariable, CreateZeroNode(indexVariable->getType()));
+ TIntermConstantUnion *arraySizeNode = CreateIndexNode(initializedNode->getOutermostArraySize());
+ TIntermBinary *indexSmallerThanSize =
+ new TIntermBinary(EOpLessThan, indexSymbolNode->deepCopy(), arraySizeNode);
+ TIntermUnary *indexIncrement =
+ new TIntermUnary(EOpPreIncrement, indexSymbolNode->deepCopy(), nullptr);
+
+ TIntermBlock *forLoopBody = new TIntermBlock();
+ TIntermSequence *forLoopBodySeq = forLoopBody->getSequence();
+
+ TIntermBinary *element = new TIntermBinary(EOpIndexIndirect, initializedNode->deepCopy(),
+ indexSymbolNode->deepCopy());
+ AddZeroInitSequence(element, true, highPrecisionSupported, forLoopBodySeq, symbolTable);
+
+ TIntermLoop *forLoop =
+ new TIntermLoop(ELoopFor, indexInit, indexSmallerThanSize, indexIncrement, forLoopBody);
+ initSequenceOut->push_back(forLoop);
+}
+
+void AddArrayZeroInitSequence(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable)
+{
+ // The array elements are assigned one by one to keep the AST compatible with ESSL 1.00 which
+ // doesn't have array assignment. We'll do this either with a for loop or just a list of
+ // statements assigning to each array index. Note that it is important to have the array init in
+ // the right order to workaround http://crbug.com/709317
+ bool isSmallArray = initializedNode->getOutermostArraySize() <= 1u ||
+ (initializedNode->getBasicType() != EbtStruct &&
+ !initializedNode->getType().isArrayOfArrays() &&
+ initializedNode->getOutermostArraySize() <= 3u);
+ if (initializedNode->getQualifier() == EvqFragData ||
+ initializedNode->getQualifier() == EvqFragmentOut || isSmallArray ||
+ !canUseLoopsToInitialize)
+ {
+ // Fragment outputs should not be indexed by non-constant indices.
+ // Also it doesn't make sense to use loops to initialize very small arrays.
+ AddArrayZeroInitStatementList(initializedNode, canUseLoopsToInitialize,
+ highPrecisionSupported, initSequenceOut, symbolTable);
+ }
+ else
+ {
+ AddArrayZeroInitForLoop(initializedNode, highPrecisionSupported, initSequenceOut,
+ symbolTable);
+ }
+}
+
+void InsertInitCode(TCompiler *compiler,
+ TIntermSequence *mainBody,
+ const InitVariableList &variables,
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported)
+{
+ for (const ShaderVariable &var : variables)
+ {
+ // Note that tempVariableName will reference a short-lived char array here - that's fine
+ // since we're only using it to find symbols.
+ ImmutableString tempVariableName(var.name.c_str(), var.name.length());
+
+ TIntermTyped *initializedSymbol = nullptr;
+ if (var.isBuiltIn() && !symbolTable->findUserDefined(tempVariableName))
+ {
+ initializedSymbol =
+ ReferenceBuiltInVariable(tempVariableName, *symbolTable, shaderVersion);
+ if (initializedSymbol->getQualifier() == EvqFragData &&
+ !IsExtensionEnabled(extensionBehavior, TExtension::EXT_draw_buffers))
+ {
+ // If GL_EXT_draw_buffers is disabled, only the 0th index of gl_FragData can be
+ // written to.
+ // TODO(oetuaho): This is a bit hacky and would be better to remove, if we came up
+ // with a good way to do it. Right now "gl_FragData" in symbol table is initialized
+ // to have the array size of MaxDrawBuffers, and the initialization happens before
+ // the shader sets the extensions it is using.
+ initializedSymbol =
+ new TIntermBinary(EOpIndexDirect, initializedSymbol, CreateIndexNode(0));
+ }
+ }
+ else
+ {
+ if (tempVariableName != "")
+ {
+ initializedSymbol = ReferenceGlobalVariable(tempVariableName, *symbolTable);
+ }
+ else
+ {
+ // Must be a nameless interface block.
+ ASSERT(var.structOrBlockName != "");
+ const TSymbol *symbol = symbolTable->findGlobal(var.structOrBlockName);
+ ASSERT(symbol && symbol->isInterfaceBlock());
+ const TInterfaceBlock *block = static_cast<const TInterfaceBlock *>(symbol);
+
+ for (const TField *field : block->fields())
+ {
+ initializedSymbol = ReferenceGlobalVariable(field->name(), *symbolTable);
+
+ TIntermSequence initCode;
+ CreateInitCode(initializedSymbol, canUseLoopsToInitialize,
+ highPrecisionSupported, &initCode, symbolTable);
+ mainBody->insert(mainBody->begin(), initCode.begin(), initCode.end());
+ }
+ // Already inserted init code in this case
+ continue;
+ }
+ }
+ ASSERT(initializedSymbol != nullptr);
+
+ TIntermSequence initCode;
+ CreateInitCode(initializedSymbol, canUseLoopsToInitialize, highPrecisionSupported,
+ &initCode, symbolTable);
+ mainBody->insert(mainBody->begin(), initCode.begin(), initCode.end());
+ }
+}
+
+class InitializeLocalsTraverser : public TIntermTraverser
+{
+ public:
+ InitializeLocalsTraverser(int shaderVersion,
+ TSymbolTable *symbolTable,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mShaderVersion(shaderVersion),
+ mCanUseLoopsToInitialize(canUseLoopsToInitialize),
+ mHighPrecisionSupported(highPrecisionSupported)
+ {}
+
+ protected:
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ for (TIntermNode *declarator : *node->getSequence())
+ {
+ if (!mInGlobalScope && !declarator->getAsBinaryNode())
+ {
+ TIntermSymbol *symbol = declarator->getAsSymbolNode();
+ ASSERT(symbol);
+ if (symbol->variable().symbolType() == SymbolType::Empty)
+ {
+ continue;
+ }
+
+ // Arrays may need to be initialized one element at a time, since ESSL 1.00 does not
+ // support array constructors or assigning arrays.
+ bool arrayConstructorUnavailable =
+ (symbol->isArray() || symbol->getType().isStructureContainingArrays()) &&
+ mShaderVersion == 100;
+ // Nameless struct constructors can't be referred to, so they also need to be
+ // initialized one element at a time.
+ // TODO(oetuaho): Check if it makes sense to initialize using a loop, even if we
+ // could use an initializer. It could at least reduce code size for very large
+ // arrays, but could hurt runtime performance.
+ if (arrayConstructorUnavailable || symbol->getType().isNamelessStruct())
+ {
+ // SimplifyLoopConditions should have been run so the parent node of this node
+ // should not be a loop.
+ ASSERT(getParentNode()->getAsLoopNode() == nullptr);
+ // SeparateDeclarations should have already been run, so we don't need to worry
+ // about further declarators in this declaration depending on the effects of
+ // this declarator.
+ ASSERT(node->getSequence()->size() == 1);
+ TIntermSequence initCode;
+ CreateInitCode(symbol, mCanUseLoopsToInitialize, mHighPrecisionSupported,
+ &initCode, mSymbolTable);
+ insertStatementsInParentBlock(TIntermSequence(), initCode);
+ }
+ else
+ {
+ TIntermBinary *init =
+ new TIntermBinary(EOpInitialize, symbol, CreateZeroNode(symbol->getType()));
+ queueReplacementWithParent(node, symbol, init, OriginalNode::BECOMES_CHILD);
+ }
+ }
+ }
+ return false;
+ }
+
+ private:
+ int mShaderVersion;
+ bool mCanUseLoopsToInitialize;
+ bool mHighPrecisionSupported;
+};
+
+} // namespace
+
+void CreateInitCode(const TIntermTyped *initializedSymbol,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initCode,
+ TSymbolTable *symbolTable)
+{
+ AddZeroInitSequence(initializedSymbol, canUseLoopsToInitialize, highPrecisionSupported,
+ initCode, symbolTable);
+}
+
+bool InitializeUninitializedLocals(TCompiler *compiler,
+ TIntermBlock *root,
+ int shaderVersion,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TSymbolTable *symbolTable)
+{
+ InitializeLocalsTraverser traverser(shaderVersion, symbolTable, canUseLoopsToInitialize,
+ highPrecisionSupported);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+bool InitializeVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ const InitVariableList &vars,
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported)
+{
+ TIntermBlock *body = FindMainBody(root);
+ InsertInitCode(compiler, body->getSequence(), vars, symbolTable, shaderVersion,
+ extensionBehavior, canUseLoopsToInitialize, highPrecisionSupported);
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.h
new file mode 100644
index 0000000000..755b8d72eb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.h
@@ -0,0 +1,60 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_INITIALIZEVARIABLES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_INITIALIZEVARIABLES_H_
+
+#include <GLSLANG/ShaderLang.h>
+
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+class TCompiler;
+class TSymbolTable;
+
+typedef std::vector<sh::ShaderVariable> InitVariableList;
+
+// For all of the functions below: If canUseLoopsToInitialize is set, for loops are used instead of
+// a large number of initializers where it can make sense, such as for initializing large arrays.
+
+// Populate a sequence of assignment operations to initialize "initializedSymbol". initializedSymbol
+// may be an array, struct or any combination of these, as long as it contains only basic types.
+void CreateInitCode(const TIntermTyped *initializedSymbol,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initCode,
+ TSymbolTable *symbolTable);
+
+// Initialize all uninitialized local variables, so that undefined behavior is avoided.
+[[nodiscard]] bool InitializeUninitializedLocals(TCompiler *compiler,
+ TIntermBlock *root,
+ int shaderVersion,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TSymbolTable *symbolTable);
+
+// This function can initialize all the types that CreateInitCode is able to initialize. All
+// variables must be globals which can be found in the symbol table. For now it is used for the
+// following two scenarios:
+// 1. Initializing gl_Position;
+// 2. Initializing output variables referred to in the shader source.
+// Note: The type of each lvalue in an initializer is retrieved from the symbol table. gl_FragData
+// requires special handling because the number of indices which can be initialized is determined by
+// enabled extensions.
+[[nodiscard]] bool InitializeVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ const InitVariableList &vars,
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_INITIALIZEVARIABLES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.cpp
new file mode 100644
index 0000000000..11c8b72002
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.cpp
@@ -0,0 +1,613 @@
+//
+// Copyright 2021 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// MonomorphizeUnsupportedFunctions: Monomorphize functions that are called with
+// parameters that are incompatible with both Vulkan GLSL and Metal.
+//
+
+#include "compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h"
+
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+struct Argument
+{
+ size_t argumentIndex;
+ TIntermTyped *argument;
+};
+
+struct FunctionData
+{
+ // Whether the original function is used. If this is false, the function can be removed because
+ // all callers have been modified.
+ bool isOriginalUsed;
+ // The original definition of the function, used to create the monomorphized version.
+ TIntermFunctionDefinition *originalDefinition;
+ // List of monomorphized versions of this function. They will be added next to the original
+ // version (or replace it).
+ TVector<TIntermFunctionDefinition *> monomorphizedDefinitions;
+};
+
+using FunctionMap = angle::HashMap<const TFunction *, FunctionData>;
+
+// Traverse the function definitions and initialize the map. Allows visitAggregate to have access
+// to TIntermFunctionDefinition even when the function is only forward declared at that point.
+void InitializeFunctionMap(TIntermBlock *root, FunctionMap *functionMapOut)
+{
+ TIntermSequence &sequence = *root->getSequence();
+
+ for (TIntermNode *node : sequence)
+ {
+ TIntermFunctionDefinition *asFuncDef = node->getAsFunctionDefinition();
+ if (asFuncDef != nullptr)
+ {
+ const TFunction *function = asFuncDef->getFunction();
+ ASSERT(function && functionMapOut->find(function) == functionMapOut->end());
+ (*functionMapOut)[function] = FunctionData{false, asFuncDef, {}};
+ }
+ }
+}
+
+const TVariable *GetBaseUniform(TIntermTyped *node, bool *isSamplerInStructOut)
+{
+ *isSamplerInStructOut = false;
+
+ while (node->getAsBinaryNode())
+ {
+ TIntermBinary *asBinary = node->getAsBinaryNode();
+
+ TOperator op = asBinary->getOp();
+
+ // No opaque uniform can be inside an interface block.
+ if (op == EOpIndexDirectInterfaceBlock)
+ {
+ return nullptr;
+ }
+
+ if (op == EOpIndexDirectStruct)
+ {
+ *isSamplerInStructOut = true;
+ }
+
+ node = asBinary->getLeft();
+ }
+
+ // Only interested in uniform opaque types. If a function call within another function uses
+ // opaque uniforms in an unsupported way, it will be replaced in a follow up pass after the
+ // calling function is monomorphized.
+ if (node->getType().getQualifier() != EvqUniform)
+ {
+ return nullptr;
+ }
+
+ ASSERT(IsOpaqueType(node->getType().getBasicType()) ||
+ node->getType().isStructureContainingSamplers());
+
+ TIntermSymbol *asSymbol = node->getAsSymbolNode();
+ ASSERT(asSymbol);
+
+ return &asSymbol->variable();
+}
+
+TIntermTyped *ExtractSideEffects(TSymbolTable *symbolTable,
+ TIntermTyped *node,
+ TIntermSequence *replacementIndices)
+{
+ TIntermTyped *withoutSideEffects = node->deepCopy();
+
+ for (TIntermBinary *asBinary = withoutSideEffects->getAsBinaryNode(); asBinary;
+ asBinary = asBinary->getLeft()->getAsBinaryNode())
+ {
+ TOperator op = asBinary->getOp();
+ TIntermTyped *index = asBinary->getRight();
+
+ if (op == EOpIndexDirectStruct)
+ {
+ break;
+ }
+
+ // No side effects with constant expressions.
+ if (op == EOpIndexDirect)
+ {
+ ASSERT(index->getAsConstantUnion());
+ continue;
+ }
+
+ ASSERT(op == EOpIndexIndirect);
+
+ // If the index is a symbol, there's no side effect, so leave it as-is.
+ if (index->getAsSymbolNode())
+ {
+ continue;
+ }
+
+ // Otherwise create a temp variable initialized with the index and use that temp variable as
+ // the index.
+ TIntermDeclaration *tempDecl = nullptr;
+ TVariable *tempVar = DeclareTempVariable(symbolTable, index, EvqTemporary, &tempDecl);
+
+ replacementIndices->push_back(tempDecl);
+ asBinary->replaceChildNode(index, new TIntermSymbol(tempVar));
+ }
+
+ return withoutSideEffects;
+}
+
+void CreateMonomorphizedFunctionCallArgs(const TIntermSequence &originalCallArguments,
+ const TVector<Argument> &replacedArguments,
+ TIntermSequence *substituteArgsOut)
+{
+ size_t nextReplacedArg = 0;
+ for (size_t argIndex = 0; argIndex < originalCallArguments.size(); ++argIndex)
+ {
+ if (nextReplacedArg >= replacedArguments.size() ||
+ argIndex != replacedArguments[nextReplacedArg].argumentIndex)
+ {
+ // Not replaced, keep argument as is.
+ substituteArgsOut->push_back(originalCallArguments[argIndex]);
+ }
+ else
+ {
+ TIntermTyped *argument = replacedArguments[nextReplacedArg].argument;
+
+ // Iterate over indices of the argument and create a new arg for every non-const
+ // index. Note that the index itself may be an expression, and it may require further
+ // substitution in the next pass.
+ while (argument->getAsBinaryNode())
+ {
+ TIntermBinary *asBinary = argument->getAsBinaryNode();
+ if (asBinary->getOp() == EOpIndexIndirect)
+ {
+ TIntermTyped *index = asBinary->getRight();
+ substituteArgsOut->push_back(index->deepCopy());
+ }
+ argument = asBinary->getLeft();
+ }
+
+ ++nextReplacedArg;
+ }
+ }
+}
+
+const TFunction *MonomorphizeFunction(TSymbolTable *symbolTable,
+ const TFunction *original,
+ TVector<Argument> *replacedArguments,
+ VariableReplacementMap *argumentMapOut)
+{
+ TFunction *substituteFunction =
+ new TFunction(symbolTable, kEmptyImmutableString, SymbolType::AngleInternal,
+ &original->getReturnType(), original->isKnownToNotHaveSideEffects());
+
+ size_t nextReplacedArg = 0;
+ for (size_t paramIndex = 0; paramIndex < original->getParamCount(); ++paramIndex)
+ {
+ const TVariable *originalParam = original->getParam(paramIndex);
+
+ if (nextReplacedArg >= replacedArguments->size() ||
+ paramIndex != (*replacedArguments)[nextReplacedArg].argumentIndex)
+ {
+ TVariable *substituteArgument =
+ new TVariable(symbolTable, originalParam->name(), &originalParam->getType(),
+ originalParam->symbolType());
+ // Not replaced, add an identical parameter.
+ substituteFunction->addParameter(substituteArgument);
+ (*argumentMapOut)[originalParam] = new TIntermSymbol(substituteArgument);
+ }
+ else
+ {
+ TIntermTyped *substituteArgument = (*replacedArguments)[nextReplacedArg].argument;
+ (*argumentMapOut)[originalParam] = substituteArgument;
+
+ // Iterate over indices of the argument and create a new parameter for every non-const
+ // index (which may be an expression). Replace the symbol in the argument with a
+ // variable of the index type. This is later used to replace the parameter in the
+ // function body.
+ while (substituteArgument->getAsBinaryNode())
+ {
+ TIntermBinary *asBinary = substituteArgument->getAsBinaryNode();
+ if (asBinary->getOp() == EOpIndexIndirect)
+ {
+ TIntermTyped *index = asBinary->getRight();
+ TType *indexType = new TType(index->getType());
+ indexType->setQualifier(EvqParamIn);
+
+ TVariable *param = new TVariable(symbolTable, kEmptyImmutableString, indexType,
+ SymbolType::AngleInternal);
+ substituteFunction->addParameter(param);
+
+ // The argument now uses the function parameters as indices.
+ asBinary->replaceChildNode(asBinary->getRight(), new TIntermSymbol(param));
+ }
+ substituteArgument = asBinary->getLeft();
+ }
+
+ ++nextReplacedArg;
+ }
+ }
+
+ return substituteFunction;
+}
+
+class MonomorphizeTraverser final : public TIntermTraverser
+{
+ public:
+ explicit MonomorphizeTraverser(TCompiler *compiler,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ UnsupportedFunctionArgsBitSet unsupportedFunctionArgs,
+ FunctionMap *functionMap)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mCompiler(compiler),
+ mCompileOptions(compileOptions),
+ mUnsupportedFunctionArgs(unsupportedFunctionArgs),
+ mFunctionMap(functionMap)
+ {}
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (node->getOp() != EOpCallFunctionInAST)
+ {
+ return true;
+ }
+
+ const TFunction *function = node->getFunction();
+ ASSERT(function && mFunctionMap->find(function) != mFunctionMap->end());
+
+ FunctionData &data = (*mFunctionMap)[function];
+
+ TIntermFunctionDefinition *monomorphized =
+ processFunctionCall(node, data.originalDefinition, &data.isOriginalUsed);
+ if (monomorphized)
+ {
+ data.monomorphizedDefinitions.push_back(monomorphized);
+ }
+
+ return true;
+ }
+
+ bool getAnyMonomorphized() const { return mAnyMonomorphized; }
+
+ private:
+ bool isUnsupportedArgument(TIntermTyped *callArgument, const TVariable *funcArgument) const
+ {
+ // Only interested in opaque uniforms and structs that contain samplers.
+ const bool isOpaqueType = IsOpaqueType(funcArgument->getType().getBasicType());
+ const bool isStructContainingSamplers =
+ funcArgument->getType().isStructureContainingSamplers();
+ if (!isOpaqueType && !isStructContainingSamplers)
+ {
+ return false;
+ }
+
+ // If not uniform (the variable was itself a function parameter), don't process it in
+ // this pass, as we don't know which actual uniform it corresponds to.
+ bool isSamplerInStruct = false;
+ const TVariable *uniform = GetBaseUniform(callArgument, &isSamplerInStruct);
+ if (uniform == nullptr)
+ {
+ return false;
+ }
+
+ const TType &type = uniform->getType();
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::StructContainingSamplers])
+ {
+ // Monomorphize if the parameter is a structure that contains samplers (so in
+ // RewriteStructSamplers we don't need to rewrite the functions to accept multiple
+ // parameters split from the struct).
+ if (isStructContainingSamplers)
+ {
+ return true;
+ }
+ }
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::ArrayOfArrayOfSamplerOrImage])
+ {
+ // Monomorphize if:
+ //
+ // - The opaque uniform is a sampler in a struct (which can create an array-of-array
+ // situation), and the function expects an array of samplers, or
+ //
+ // - The opaque uniform is an array of array of sampler or image, and it's partially
+ // subscripted (i.e. the function itself expects an array)
+ //
+ const bool isParameterArrayOfOpaqueType = funcArgument->getType().isArray();
+ const bool isArrayOfArrayOfSamplerOrImage =
+ (type.isSampler() || type.isImage()) && type.isArrayOfArrays();
+ if (isSamplerInStruct && isParameterArrayOfOpaqueType)
+ {
+ return true;
+ }
+ if (isArrayOfArrayOfSamplerOrImage && isParameterArrayOfOpaqueType)
+ {
+ return true;
+ }
+ }
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::AtomicCounter])
+ {
+ if (type.isAtomicCounter())
+ {
+ return true;
+ }
+ }
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::SamplerCubeEmulation])
+ {
+ // Monomorphize if the opaque uniform is a samplerCube and ES2's cube sampling emulation
+ // is requested.
+ if (type.isSamplerCube() && mCompileOptions.emulateSeamfulCubeMapSampling)
+ {
+ return true;
+ }
+ }
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::Image])
+ {
+ if (type.isImage())
+ {
+ return true;
+ }
+ }
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::PixelLocalStorage])
+ {
+ if (type.isPixelLocal())
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ TIntermFunctionDefinition *processFunctionCall(TIntermAggregate *functionCall,
+ TIntermFunctionDefinition *originalDefinition,
+ bool *isOriginalUsedOut)
+ {
+ const TFunction *function = functionCall->getFunction();
+ const TIntermSequence &callArguments = *functionCall->getSequence();
+
+ TVector<Argument> replacedArguments;
+ TIntermSequence replacementIndices;
+
+ // Go through function call arguments, and see if any is used in an unsupported way.
+ for (size_t argIndex = 0; argIndex < callArguments.size(); ++argIndex)
+ {
+ TIntermTyped *callArgument = callArguments[argIndex]->getAsTyped();
+ const TVariable *funcArgument = function->getParam(argIndex);
+ if (isUnsupportedArgument(callArgument, funcArgument))
+ {
+ // Copy the argument and extract the side effects.
+ TIntermTyped *argument =
+ ExtractSideEffects(mSymbolTable, callArgument, &replacementIndices);
+
+ replacedArguments.push_back({argIndex, argument});
+ }
+ }
+
+ if (replacedArguments.empty())
+ {
+ *isOriginalUsedOut = true;
+ return nullptr;
+ }
+
+ mAnyMonomorphized = true;
+
+ insertStatementsInParentBlock(replacementIndices);
+
+ // Create the arguments for the substitute function call. Done before monomorphizing the
+ // function, which transforms the arguments to what needs to be replaced in the function
+ // body.
+ TIntermSequence newCallArgs;
+ CreateMonomorphizedFunctionCallArgs(callArguments, replacedArguments, &newCallArgs);
+
+ // Duplicate the function and substitute the replaced arguments with only the non-const
+ // indices. Additionally, substitute the non-const indices of arguments with the new
+ // function parameters.
+ VariableReplacementMap argumentMap;
+ const TFunction *monomorphized =
+ MonomorphizeFunction(mSymbolTable, function, &replacedArguments, &argumentMap);
+
+ // Replace this function call with a call to the new one.
+ queueReplacement(TIntermAggregate::CreateFunctionCall(*monomorphized, &newCallArgs),
+ OriginalNode::IS_DROPPED);
+
+ // Create a new function definition, with the body of the old function but with the replaced
+ // parameters substituted with the calling expressions.
+ TIntermFunctionPrototype *substitutePrototype = new TIntermFunctionPrototype(monomorphized);
+ TIntermBlock *substituteBlock = originalDefinition->getBody()->deepCopy();
+ GetDeclaratorReplacements(mSymbolTable, substituteBlock, &argumentMap);
+ bool valid = ReplaceVariables(mCompiler, substituteBlock, argumentMap);
+ ASSERT(valid);
+
+ return new TIntermFunctionDefinition(substitutePrototype, substituteBlock);
+ }
+
+ TCompiler *mCompiler;
+ const ShCompileOptions &mCompileOptions;
+ UnsupportedFunctionArgsBitSet mUnsupportedFunctionArgs;
+ bool mAnyMonomorphized = false;
+
+ // Map of original to monomorphized functions.
+ FunctionMap *mFunctionMap;
+};
+
+class UpdateFunctionsDefinitionsTraverser final : public TIntermTraverser
+{
+ public:
+ explicit UpdateFunctionsDefinitionsTraverser(TSymbolTable *symbolTable,
+ const FunctionMap &functionMap)
+ : TIntermTraverser(true, false, false, symbolTable), mFunctionMap(functionMap)
+ {}
+
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override
+ {
+ const bool isInFunctionDefinition = getParentNode()->getAsFunctionDefinition() != nullptr;
+ if (isInFunctionDefinition)
+ {
+ return;
+ }
+
+ // Add to and possibly replace the function prototype with replacement prototypes.
+ const TFunction *function = node->getFunction();
+ ASSERT(function && mFunctionMap.find(function) != mFunctionMap.end());
+
+ const FunctionData &data = mFunctionMap.at(function);
+
+ // If nothing to do, leave it be.
+ if (data.monomorphizedDefinitions.empty())
+ {
+ ASSERT(data.isOriginalUsed);
+ return;
+ }
+
+ // Replace the prototype with itself (if function is still used) as well as any
+ // monomorphized versions.
+ TIntermSequence replacement;
+ if (data.isOriginalUsed)
+ {
+ replacement.push_back(node);
+ }
+ for (TIntermFunctionDefinition *monomorphizedDefinition : data.monomorphizedDefinitions)
+ {
+ replacement.push_back(new TIntermFunctionPrototype(
+ monomorphizedDefinition->getFunctionPrototype()->getFunction()));
+ }
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(replacement));
+ }
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ // Add to and possibly replace the function definition with replacement definitions.
+ const TFunction *function = node->getFunction();
+ ASSERT(function && mFunctionMap.find(function) != mFunctionMap.end());
+
+ const FunctionData &data = mFunctionMap.at(function);
+
+ // If nothing to do, leave it be.
+ if (data.monomorphizedDefinitions.empty())
+ {
+ ASSERT(data.isOriginalUsed || function->name() == "main");
+ return false;
+ }
+
+ // Replace the definition with itself (if function is still used) as well as any
+ // monomorphized versions.
+ TIntermSequence replacement;
+ if (data.isOriginalUsed)
+ {
+ replacement.push_back(node);
+ }
+ for (TIntermFunctionDefinition *monomorphizedDefinition : data.monomorphizedDefinitions)
+ {
+ replacement.push_back(monomorphizedDefinition);
+ }
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(replacement));
+
+ return false;
+ }
+
+ private:
+ const FunctionMap &mFunctionMap;
+};
+
+void SortDeclarations(TIntermBlock *root)
+{
+ TIntermSequence *original = root->getSequence();
+
+ TIntermSequence replacement;
+ TIntermSequence functionDefs;
+
+ // Accumulate non-function-definition declarations in |replacement| and function definitions in
+ // |functionDefs|.
+ for (TIntermNode *node : *original)
+ {
+ if (node->getAsFunctionDefinition() || node->getAsFunctionPrototypeNode())
+ {
+ functionDefs.push_back(node);
+ }
+ else
+ {
+ replacement.push_back(node);
+ }
+ }
+
+ // Append function definitions to |replacement|.
+ replacement.insert(replacement.end(), functionDefs.begin(), functionDefs.end());
+
+ // Replace root's sequence with |replacement|.
+ root->replaceAllChildren(replacement);
+}
+
+bool MonomorphizeUnsupportedFunctionsImpl(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ UnsupportedFunctionArgsBitSet unsupportedFunctionArgs)
+{
+ // First, sort out the declarations such that all non-function declarations are placed before
+ // function definitions. This way when the function is replaced with one that references said
+ // declarations (i.e. uniforms), the uniform declaration is already present above it.
+ SortDeclarations(root);
+
+ while (true)
+ {
+ FunctionMap functionMap;
+ InitializeFunctionMap(root, &functionMap);
+
+ MonomorphizeTraverser monomorphizer(compiler, symbolTable, compileOptions,
+ unsupportedFunctionArgs, &functionMap);
+ root->traverse(&monomorphizer);
+
+ if (!monomorphizer.getAnyMonomorphized())
+ {
+ break;
+ }
+
+ if (!monomorphizer.updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ UpdateFunctionsDefinitionsTraverser functionUpdater(symbolTable, functionMap);
+ root->traverse(&functionUpdater);
+
+ if (!functionUpdater.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+} // anonymous namespace
+
+bool MonomorphizeUnsupportedFunctions(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ UnsupportedFunctionArgsBitSet unsupportedFunctionArgs)
+{
+ // This function actually applies multiple transformation, and the AST may not be valid until
+ // the transformations are entirely done. Some validation is momentarily disabled.
+ bool enableValidateFunctionCall = compiler->disableValidateFunctionCall();
+
+ bool result = MonomorphizeUnsupportedFunctionsImpl(compiler, root, symbolTable, compileOptions,
+ unsupportedFunctionArgs);
+
+ compiler->restoreValidateFunctionCall(enableValidateFunctionCall);
+ return result && compiler->validateAST(root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h
new file mode 100644
index 0000000000..a9a212704b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h
@@ -0,0 +1,54 @@
+//
+// Copyright 2021 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// MonomorphizeUnsupportedFunctions: Monomorphize functions that are called with
+// parameters that are incompatible with both Vulkan GLSL and Metal:
+//
+// - Samplers in structs
+// - Structs that have samplers
+// - Partially subscripted array of array of samplers
+// - Partially subscripted array of array of images
+// - Atomic counters
+// - samplerCube variables when emulating ES2's cube map sampling
+// - image* variables with r32f formats (to emulate imageAtomicExchange)
+//
+// This transformation basically duplicates such functions, removes the
+// sampler/image/atomic_counter parameters and uses the opaque uniforms used by the caller.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_VULKAN_MONOMORPHIZEUNSUPPORTEDFUNCTIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_VULKAN_MONOMORPHIZEUNSUPPORTEDFUNCTIONS_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+class TIntermBlock;
+class TSymbolTable;
+
+// Types of function prameters that should trigger monomorphization.
+enum class UnsupportedFunctionArgs
+{
+ StructContainingSamplers = 0,
+ ArrayOfArrayOfSamplerOrImage = 1,
+ AtomicCounter = 2,
+ SamplerCubeEmulation = 3,
+ Image = 4,
+ PixelLocalStorage = 5,
+
+ InvalidEnum = 6,
+ EnumCount = 6,
+};
+
+using UnsupportedFunctionArgsBitSet = angle::PackedEnumBitSet<UnsupportedFunctionArgs>;
+
+[[nodiscard]] bool MonomorphizeUnsupportedFunctions(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ UnsupportedFunctionArgsBitSet);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_VULKAN_MONOMORPHIZEUNSUPPORTEDFUNCTIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.cpp
new file mode 100644
index 0000000000..a23d0770ef
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.cpp
@@ -0,0 +1,127 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// NameNamelessUniformBuffers: Gives nameless uniform buffer variables internal names.
+//
+
+#include "compiler/translator/tree_ops/NameNamelessUniformBuffers.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+// Traverse uniform buffer declarations and give name to nameless declarations. Keeps track of
+// the interface fields which will be used in the source without the interface block variable name
+// and replaces them with name.field.
+class NameUniformBufferVariablesTraverser : public TIntermTraverser
+{
+ public:
+ explicit NameUniformBufferVariablesTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *decl) override
+ {
+ ASSERT(visit == PreVisit);
+
+ const TIntermSequence &sequence = *(decl->getSequence());
+
+ TIntermTyped *variableNode = sequence.front()->getAsTyped();
+ const TType &type = variableNode->getType();
+
+ // If it's an interface block, it may have to be converted if it contains any row-major
+ // fields.
+ if (!type.isInterfaceBlock())
+ {
+ return true;
+ }
+
+ // Multi declaration statements are already separated, so there can only be one variable
+ // here.
+ ASSERT(sequence.size() == 1);
+ const TVariable *variable = &variableNode->getAsSymbolNode()->variable();
+ if (variable->symbolType() != SymbolType::Empty)
+ {
+ return false;
+ }
+
+ TIntermDeclaration *newDeclaration = new TIntermDeclaration;
+ TVariable *newVariable = new TVariable(mSymbolTable, kEmptyImmutableString, &type,
+ SymbolType::AngleInternal, variable->extensions());
+ newDeclaration->appendDeclarator(new TIntermSymbol(newVariable));
+
+ queueReplacement(newDeclaration, OriginalNode::IS_DROPPED);
+
+ // It's safe to key the map with the interface block, as there couldn't have been multiple
+ // declarations with this interface block (as the variable is nameless), so for nameless
+ // uniform buffers, the interface block is unique.
+ mNamelessUniformBuffersMap[type.getInterfaceBlock()] = newVariable;
+
+ return false;
+ }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ const TType &type = symbol->getType();
+
+ // The symbols we are looking for have the interface block pointer set, but are not
+ // interface blocks. These are references to fields of nameless uniform buffers.
+ if (type.isInterfaceBlock() || type.getInterfaceBlock() == nullptr)
+ {
+ return;
+ }
+
+ const TInterfaceBlock *block = type.getInterfaceBlock();
+
+ // If block variable is not nameless, there's nothing to do.
+ if (mNamelessUniformBuffersMap.count(block) == 0)
+ {
+ return;
+ }
+
+ const ImmutableString symbolName = symbol->getName();
+
+ // Find which field it is
+ const TVector<TField *> fields = block->fields();
+ for (size_t fieldIndex = 0; fieldIndex < fields.size(); ++fieldIndex)
+ {
+ const TField *field = fields[fieldIndex];
+ if (field->name() != symbolName)
+ {
+ continue;
+ }
+
+ // Replace this node with a binary node that indexes the named uniform buffer.
+ TIntermSymbol *namedUniformBuffer =
+ new TIntermSymbol(mNamelessUniformBuffersMap[block]);
+ TIntermBinary *replacement =
+ new TIntermBinary(EOpIndexDirectInterfaceBlock, namedUniformBuffer,
+ CreateIndexNode(static_cast<uint32_t>(fieldIndex)));
+
+ queueReplacement(replacement, OriginalNode::IS_DROPPED);
+
+ return;
+ }
+
+ UNREACHABLE();
+ }
+
+ private:
+ // A map from nameless uniform buffers to their named replacements.
+ std::unordered_map<const TInterfaceBlock *, const TVariable *> mNamelessUniformBuffersMap;
+};
+} // anonymous namespace
+
+bool NameNamelessUniformBuffers(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ NameUniformBufferVariablesTraverser nameUniformBufferVariables(symbolTable);
+ root->traverse(&nameUniformBufferVariables);
+ return nameUniformBufferVariables.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.h
new file mode 100644
index 0000000000..23964a5846
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// NameNamelessUniformBuffers: Gives nameless uniform buffer variables internal names.
+//
+// For example:
+// uniform UniformBuffer { int a; };
+// x = a;
+// becomes:
+// uniform UniformBuffer { int a; } s123;
+// x = s123.a;
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_NAMENAMELESSUNIFORMBUFFERS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_NAMENAMELESSUNIFORMBUFFERS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool NameNamelessUniformBuffers(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_NAMENAMELESSUNIFORMBUFFERS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp
new file mode 100644
index 0000000000..276c8c98ed
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp
@@ -0,0 +1,127 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// PruneEmptyCases.cpp: The PruneEmptyCases function prunes cases that are followed by nothing from
+// the AST.
+
+#include "compiler/translator/tree_ops/PruneEmptyCases.h"
+
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+bool AreEmptyBlocks(const TIntermSequence *statements);
+
+bool IsEmptyBlock(TIntermNode *node)
+{
+ TIntermBlock *asBlock = node->getAsBlock();
+ if (asBlock)
+ {
+ return AreEmptyBlocks(asBlock->getSequence());
+ }
+ // Empty declarations should have already been pruned, otherwise they would need to be handled
+ // here. Note that declarations for struct types do contain a nameless child node.
+ ASSERT(node->getAsDeclarationNode() == nullptr ||
+ !node->getAsDeclarationNode()->getSequence()->empty());
+ // Pure literal statements should also already be pruned.
+ ASSERT(node->getAsConstantUnion() == nullptr);
+ return false;
+}
+
+// Return true if all statements in "statements" consist only of empty blocks and no-op statements.
+// Returns true also if there are no statements.
+bool AreEmptyBlocks(const TIntermSequence *statements)
+{
+ for (size_t i = 0u; i < statements->size(); ++i)
+ {
+ if (!IsEmptyBlock(statements->at(i)))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+class PruneEmptyCasesTraverser : private TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool apply(TCompiler *compiler, TIntermBlock *root);
+
+ private:
+ PruneEmptyCasesTraverser();
+ bool visitSwitch(Visit visit, TIntermSwitch *node) override;
+};
+
+bool PruneEmptyCasesTraverser::apply(TCompiler *compiler, TIntermBlock *root)
+{
+ PruneEmptyCasesTraverser prune;
+ root->traverse(&prune);
+ return prune.updateTree(compiler, root);
+}
+
+PruneEmptyCasesTraverser::PruneEmptyCasesTraverser() : TIntermTraverser(true, false, false) {}
+
+bool PruneEmptyCasesTraverser::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ // This may mutate the statementList, but that's okay, since traversal has not yet reached
+ // there.
+ TIntermBlock *statementList = node->getStatementList();
+ TIntermSequence *statements = statementList->getSequence();
+
+ // Iterate block children in reverse order. Cases that are only followed by other cases or empty
+ // blocks are marked for pruning.
+ size_t i = statements->size();
+ size_t lastNoOpInStatementList = i;
+ while (i > 0)
+ {
+ --i;
+ TIntermNode *statement = statements->at(i);
+ if (statement->getAsCaseNode() || IsEmptyBlock(statement))
+ {
+ lastNoOpInStatementList = i;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if (lastNoOpInStatementList == 0)
+ {
+ // Remove the entire switch statement, extracting the init expression if needed.
+ TIntermTyped *init = node->getInit();
+ if (init->hasSideEffects())
+ {
+ queueReplacement(init, OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ TIntermSequence emptyReplacement;
+ ASSERT(getParentNode()->getAsBlock());
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(emptyReplacement));
+ }
+ return false;
+ }
+ if (lastNoOpInStatementList < statements->size())
+ {
+ statements->erase(statements->begin() + lastNoOpInStatementList, statements->end());
+ }
+
+ return true;
+}
+
+} // namespace
+
+bool PruneEmptyCases(TCompiler *compiler, TIntermBlock *root)
+{
+ return PruneEmptyCasesTraverser::apply(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.h
new file mode 100644
index 0000000000..5098fec9b7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.h
@@ -0,0 +1,22 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// PruneEmptyCases.h: The PruneEmptyCases function prunes cases that are followed by nothing from
+// the AST.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_PRUNEEMPTYCASES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_PRUNEEMPTYCASES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+
+[[nodiscard]] bool PruneEmptyCases(TCompiler *compiler, TIntermBlock *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_PRUNEEMPTYCASES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp
new file mode 100644
index 0000000000..fdc6070660
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp
@@ -0,0 +1,215 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// PruneNoOps.cpp: The PruneNoOps function prunes:
+// 1. Empty declarations "int;". Empty declarators will be pruned as well, so for example:
+// int , a;
+// is turned into
+// int a;
+// 2. Literal statements: "1.0;". The ESSL output doesn't define a default precision for float,
+// so float literal statements would end up with no precision which is invalid ESSL.
+// 3. Statements after discard, return, break and continue.
+
+#include "compiler/translator/tree_ops/PruneNoOps.h"
+
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+bool IsNoOp(TIntermNode *node)
+{
+ if (node->getAsConstantUnion() != nullptr)
+ {
+ return true;
+ }
+ bool isEmptyDeclaration = node->getAsDeclarationNode() != nullptr &&
+ node->getAsDeclarationNode()->getSequence()->empty();
+ if (isEmptyDeclaration)
+ {
+ return true;
+ }
+ return false;
+}
+
+class PruneNoOpsTraverser : private TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool apply(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+
+ private:
+ PruneNoOpsTraverser(TSymbolTable *symbolTable);
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+ bool visitLoop(Visit visit, TIntermLoop *loop) override;
+ bool visitBranch(Visit visit, TIntermBranch *node) override;
+
+ bool mIsBranchVisited = false;
+};
+
+bool PruneNoOpsTraverser::apply(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ PruneNoOpsTraverser prune(symbolTable);
+ root->traverse(&prune);
+ return prune.updateTree(compiler, root);
+}
+
+PruneNoOpsTraverser::PruneNoOpsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, true, true, symbolTable)
+{}
+
+bool PruneNoOpsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ if (visit != PreVisit)
+ {
+ return true;
+ }
+
+ TIntermSequence *sequence = node->getSequence();
+ if (sequence->size() >= 1)
+ {
+ TIntermSymbol *declaratorSymbol = sequence->front()->getAsSymbolNode();
+ // Prune declarations without a variable name, unless it's an interface block declaration.
+ if (declaratorSymbol != nullptr &&
+ declaratorSymbol->variable().symbolType() == SymbolType::Empty &&
+ !declaratorSymbol->isInterfaceBlock())
+ {
+ if (sequence->size() > 1)
+ {
+ // Generate a replacement that will remove the empty declarator in the beginning of
+ // a declarator list. Example of a declaration that will be changed:
+ // float, a;
+ // will be changed to
+ // float a;
+ // This applies also to struct declarations.
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.emplace_back(node, declaratorSymbol,
+ std::move(emptyReplacement));
+ }
+ else if (declaratorSymbol->getBasicType() != EbtStruct)
+ {
+ // If there are entirely empty non-struct declarations, they result in
+ // TIntermDeclaration nodes without any children in the parsing stage. These are
+ // handled in visitBlock and visitLoop.
+ UNREACHABLE();
+ }
+ else if (declaratorSymbol->getQualifier() != EvqGlobal &&
+ declaratorSymbol->getQualifier() != EvqTemporary)
+ {
+ // Single struct declarations may just declare the struct type and no variables, so
+ // they should not be pruned. Here we handle an empty struct declaration with a
+ // qualifier, for example like this:
+ // const struct a { int i; };
+ // NVIDIA GL driver version 367.27 doesn't accept this kind of declarations, so we
+ // convert the declaration to a regular struct declaration. This is okay, since ESSL
+ // 1.00 spec section 4.1.8 says about structs that "The optional qualifiers only
+ // apply to any declarators, and are not part of the type being defined for name."
+
+ // Create a new variable to use in the declarator so that the variable and node
+ // types are kept consistent.
+ TType *type = new TType(declaratorSymbol->getType());
+ if (mInGlobalScope)
+ {
+ type->setQualifier(EvqGlobal);
+ }
+ else
+ {
+ type->setQualifier(EvqTemporary);
+ }
+ TVariable *variable =
+ new TVariable(mSymbolTable, kEmptyImmutableString, type, SymbolType::Empty);
+ queueReplacementWithParent(node, declaratorSymbol, new TIntermSymbol(variable),
+ OriginalNode::IS_DROPPED);
+ }
+ }
+ }
+ return false;
+}
+
+bool PruneNoOpsTraverser::visitBlock(Visit visit, TIntermBlock *node)
+{
+ ASSERT(visit == PreVisit);
+
+ TIntermSequence &statements = *node->getSequence();
+
+ // Visit each statement in the block one by one. Once a branch is visited (break, continue,
+ // return or discard), drop the rest of the statements.
+ for (size_t statementIndex = 0; statementIndex < statements.size(); ++statementIndex)
+ {
+ TIntermNode *statement = statements[statementIndex];
+
+ // If the statement is a switch case label, stop pruning and continue visiting the children.
+ if (statement->getAsCaseNode() != nullptr)
+ {
+ mIsBranchVisited = false;
+ }
+
+ // If a branch is visited, prune the statement. If the statement is a no-op, also prune it.
+ if (mIsBranchVisited || IsNoOp(statement))
+ {
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.emplace_back(node, statement, std::move(emptyReplacement));
+ continue;
+ }
+
+ // Visit the statement if not pruned.
+ statement->traverse(this);
+ }
+
+ // If the parent is a block and mIsBranchVisited is set, this is a nested block without any
+ // condition (like if, loop or switch), so the rest of the parent block should also be pruned.
+ // Otherwise the parent block should be unaffected.
+ if (mIsBranchVisited && getParentNode()->getAsBlock() == nullptr)
+ {
+ mIsBranchVisited = false;
+ }
+
+ return false;
+}
+
+bool PruneNoOpsTraverser::visitLoop(Visit visit, TIntermLoop *loop)
+{
+ if (visit != PreVisit)
+ {
+ return true;
+ }
+
+ TIntermTyped *expr = loop->getExpression();
+ if (expr != nullptr && IsNoOp(expr))
+ {
+ loop->setExpression(nullptr);
+ }
+ TIntermNode *init = loop->getInit();
+ if (init != nullptr && IsNoOp(init))
+ {
+ loop->setInit(nullptr);
+ }
+
+ return true;
+}
+
+bool PruneNoOpsTraverser::visitBranch(Visit visit, TIntermBranch *node)
+{
+ ASSERT(visit == PreVisit);
+
+ mIsBranchVisited = true;
+
+ // Only possible child is the value of a return statement, which has nothing to prune.
+ return false;
+}
+} // namespace
+
+bool PruneNoOps(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ return PruneNoOpsTraverser::apply(compiler, root, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.h
new file mode 100644
index 0000000000..a73cb71d08
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// PruneNoOps.h: The PruneNoOps function prunes:
+// 1. Empty declarations "int;". Empty declarators will be pruned as well, so for example:
+// int , a;
+// is turned into
+// int a;
+// 2. Literal statements: "1.0;". The ESSL output doesn't define a default precision for float,
+// so float literal statements would end up with no precision which is invalid ESSL.
+// 3. Statements after discard, return, break and continue.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_PRUNENOOPS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_PRUNENOOPS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool PruneNoOps(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_PRUNENOOPS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp
new file mode 100644
index 0000000000..ea15ab7844
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp
@@ -0,0 +1,119 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// During parsing, all constant expressions are folded to constant union nodes. The expressions that
+// have been folded may have had precision qualifiers, which should affect the precision of the
+// consuming operation. If the folded constant union nodes are written to output as such they won't
+// have any precision qualifiers, and their effect on the precision of the consuming operation is
+// lost.
+//
+// RecordConstantPrecision is an AST traverser that inspects the precision qualifiers of constants
+// and hoists the constants outside the containing expression as precision qualified named variables
+// in case that is required for correct precision propagation.
+//
+
+#include "compiler/translator/tree_ops/RecordConstantPrecision.h"
+
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class RecordConstantPrecisionTraverser : public TIntermTraverser
+{
+ public:
+ RecordConstantPrecisionTraverser(TSymbolTable *symbolTable);
+
+ void visitConstantUnion(TIntermConstantUnion *node) override;
+
+ protected:
+ bool operandAffectsParentOperationPrecision(TIntermTyped *operand);
+};
+
+RecordConstantPrecisionTraverser::RecordConstantPrecisionTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, true, symbolTable)
+{}
+
+bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TIntermTyped *operand)
+{
+ if (getParentNode()->getAsCaseNode() || getParentNode()->getAsBlock())
+ {
+ return false;
+ }
+
+ if (operand->getBasicType() == EbtBool || operand->getBasicType() == EbtStruct)
+ {
+ return false;
+ }
+
+ const TIntermBinary *parentAsBinary = getParentNode()->getAsBinaryNode();
+ if (parentAsBinary != nullptr)
+ {
+ // If the constant is assigned or is used to initialize a variable, or if it's an index,
+ // its precision has no effect.
+ switch (parentAsBinary->getOp())
+ {
+ case EOpInitialize:
+ case EOpAssign:
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ case EOpIndexIndirect:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ TIntermAggregate *parentAsAggregate = getParentNode()->getAsAggregate();
+ if (parentAsAggregate != nullptr)
+ {
+ // The precision of an aggregate is derived from children only in the following conditions:
+ //
+ // - Built-in math operations
+ // - Constructors
+ //
+ return parentAsAggregate->isConstructor() ||
+ BuiltInGroup::IsMath(parentAsAggregate->getOp());
+ }
+
+ return true;
+}
+
+void RecordConstantPrecisionTraverser::visitConstantUnion(TIntermConstantUnion *node)
+{
+ // If the constant has lowp or undefined precision, it can't increase the precision of consuming
+ // operations.
+ if (node->getPrecision() < EbpMedium)
+ return;
+
+ // It's possible the node has no effect on the precision of the consuming expression, depending
+ // on the consuming expression, and the precision of the other parameters of the expression.
+ if (!operandAffectsParentOperationPrecision(node))
+ return;
+
+ // Make the constant a precision-qualified named variable to make sure it affects the precision
+ // of the consuming expression.
+ TIntermDeclaration *variableDeclaration = nullptr;
+ TVariable *variable = DeclareTempVariable(mSymbolTable, node, EvqConst, &variableDeclaration);
+ insertStatementInParentBlock(variableDeclaration);
+ queueReplacement(CreateTempSymbolNode(variable), OriginalNode::IS_DROPPED);
+}
+
+} // namespace
+
+bool RecordConstantPrecision(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ RecordConstantPrecisionTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.h
new file mode 100644
index 0000000000..f615b11221
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// During parsing, all constant expressions are folded to constant union nodes. The expressions that
+// have been folded may have had precision qualifiers, which should affect the precision of the
+// consuming operation. If the folded constant union nodes are written to output as such they won't
+// have any precision qualifiers, and their effect on the precision of the consuming operation is
+// lost.
+//
+// RecordConstantPrecision is an AST traverser that inspects the precision qualifiers of constants
+// and hoists the constants outside the containing expression as precision qualified named variables
+// in case that is required for correct precision propagation.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_RECORDCONSTANTPRECISION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_RECORDCONSTANTPRECISION_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RecordConstantPrecision(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_RECORDCONSTANTPRECISION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp
new file mode 100644
index 0000000000..85ecb9346b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp
@@ -0,0 +1,109 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveArrayLengthMethod.cpp:
+// Fold array length expressions, including cases where the "this" node has side effects.
+// Example:
+// int i = (a = b).length();
+// int j = (func()).length();
+// becomes:
+// (a = b);
+// int i = <constant array length>;
+// func();
+// int j = <constant array length>;
+//
+// Must be run after SplitSequenceOperator, SimplifyLoopConditions and SeparateDeclarations steps
+// have been done to expressions containing calls of the array length method.
+//
+// Does nothing to length method calls done on runtime-sized arrays.
+
+#include "compiler/translator/tree_ops/RemoveArrayLengthMethod.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class RemoveArrayLengthTraverser : public TIntermTraverser
+{
+ public:
+ RemoveArrayLengthTraverser() : TIntermTraverser(true, false, false), mFoundArrayLength(false) {}
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+
+ void nextIteration() { mFoundArrayLength = false; }
+
+ bool foundArrayLength() const { return mFoundArrayLength; }
+
+ private:
+ void insertSideEffectsInParentBlock(TIntermTyped *node);
+
+ bool mFoundArrayLength;
+};
+
+bool RemoveArrayLengthTraverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ // The only case where we leave array length() in place is for runtime-sized arrays.
+ if (node->getOp() == EOpArrayLength && !node->getOperand()->getType().isUnsizedArray())
+ {
+ mFoundArrayLength = true;
+ insertSideEffectsInParentBlock(node->getOperand());
+ TConstantUnion *constArray = new TConstantUnion[1];
+ constArray->setIConst(node->getOperand()->getOutermostArraySize());
+ queueReplacement(new TIntermConstantUnion(constArray, node->getType()),
+ OriginalNode::IS_DROPPED);
+ return false;
+ }
+ return true;
+}
+
+void RemoveArrayLengthTraverser::insertSideEffectsInParentBlock(TIntermTyped *node)
+{
+ // If the node is an index type, traverse it and add the indices as side effects. If at the end
+ // an expression without side effect is encountered, such as an opaque uniform or a lone symbol,
+ // don't generate a statement for it.
+ if (!node->hasSideEffects())
+ {
+ return;
+ }
+
+ TIntermBinary *asBinary = node->getAsBinaryNode();
+ if (asBinary && !asBinary->isAssignment())
+ {
+ insertSideEffectsInParentBlock(asBinary->getLeft());
+ insertSideEffectsInParentBlock(asBinary->getRight());
+ }
+ else
+ {
+ insertStatementInParentBlock(node);
+ }
+}
+
+} // anonymous namespace
+
+bool RemoveArrayLengthMethod(TCompiler *compiler, TIntermBlock *root)
+{
+ RemoveArrayLengthTraverser traverser;
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.foundArrayLength())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.foundArrayLength());
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h
new file mode 100644
index 0000000000..8468e1e635
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h
@@ -0,0 +1,37 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveArrayLengthMethod.h:
+// Fold array length expressions, including cases where the "this" node has side effects.
+// Example:
+// int i = (a = b).length();
+// int j = (func()).length();
+// becomes:
+// (a = b);
+// int i = <constant array length>;
+// func();
+// int j = <constant array length>;
+//
+// Must be run after SplitSequenceOperator, SimplifyLoopConditions and SeparateDeclarations steps
+// have been done to expressions containing calls of the array length method.
+//
+// Does nothing to length method calls done on runtime-sized arrays.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEARRAYLENGTHMETHOD_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEARRAYLENGTHMETHOD_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+
+[[nodiscard]] bool RemoveArrayLengthMethod(TCompiler *compiler, TIntermBlock *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEARRAYLENGTHMETHOD_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp
new file mode 100644
index 0000000000..ed0ba3fed8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp
@@ -0,0 +1,74 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveAtomicCounterBuiltins: Remove atomic counter builtins.
+//
+
+#include "compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+
+bool IsAtomicCounterDecl(const TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+ return type.getQualifier() == EvqUniform && type.isAtomicCounter();
+}
+
+// Traverser that removes all GLSL built-ins that use AtomicCounters
+// Only called when the builtins are in use, but no atomic counters have been declared
+class RemoveAtomicCounterBuiltinsTraverser : public TIntermTraverser
+{
+ public:
+ RemoveAtomicCounterBuiltinsTraverser() : TIntermTraverser(true, false, false) {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ ASSERT(visit == PreVisit);
+
+ // Active atomic counters should have been removed by RewriteAtomicCounters, and this
+ // traversal should not have been invoked
+ ASSERT(!IsAtomicCounterDecl(node));
+ return false;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (node->getOp() == EOpMemoryBarrierAtomicCounter)
+ {
+ // Vulkan does not support atomic counters, so if this builtin finds its way here,
+ // we need to remove it.
+ TIntermSequence emptySequence;
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(emptySequence));
+ return true;
+ }
+
+ // We shouldn't see any other builtins because they cannot be present without an active
+ // atomic counter, and should have been removed by RewriteAtomicCounters. If this fires,
+ // this traversal should not have been called.
+ ASSERT(!(BuiltInGroup::IsBuiltIn(node->getOp()) &&
+ node->getFunction()->isAtomicCounterFunction()));
+
+ return false;
+ }
+};
+
+} // anonymous namespace
+
+bool RemoveAtomicCounterBuiltins(TCompiler *compiler, TIntermBlock *root)
+{
+ RemoveAtomicCounterBuiltinsTraverser traverser;
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h
new file mode 100644
index 0000000000..efe8a53595
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveAtomicCounterBuiltins: Remove atomic counter builtins.
+// Normally handled by RewriteAtomicCounters, but that is only invoked when
+// atomic counters are actually in use. This pass removes the builtins and
+// asserts no atomic counters are declared.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEATOMICCOUNTERBUILTINS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEATOMICCOUNTERBUILTINS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+
+[[nodiscard]] bool RemoveAtomicCounterBuiltins(TCompiler *compiler, TIntermBlock *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEATOMICCOUNTERBUILTINS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp
new file mode 100644
index 0000000000..fda6de6f48
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp
@@ -0,0 +1,597 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of non-SSBO vectors and
+// matrices, replacing them with calls to functions that choose which component to return or write.
+// We don't need to consider dynamic indexing in SSBO since it can be directly as part of the offset
+// of RWByteAddressBuffer.
+//
+
+#include "compiler/translator/tree_ops/RemoveDynamicIndexing.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+using DynamicIndexingNodeMatcher = std::function<bool(TIntermBinary *)>;
+
+const TType *kIndexType = StaticType::Get<EbtInt, EbpHigh, EvqParamIn, 1, 1>();
+
+constexpr const ImmutableString kBaseName("base");
+constexpr const ImmutableString kIndexName("index");
+constexpr const ImmutableString kValueName("value");
+
+std::string GetIndexFunctionName(const TType &type, bool write)
+{
+ TInfoSinkBase nameSink;
+ nameSink << "dyn_index_";
+ if (write)
+ {
+ nameSink << "write_";
+ }
+ if (type.isMatrix())
+ {
+ nameSink << "mat" << static_cast<uint32_t>(type.getCols()) << "x"
+ << static_cast<uint32_t>(type.getRows());
+ }
+ else
+ {
+ switch (type.getBasicType())
+ {
+ case EbtInt:
+ nameSink << "ivec";
+ break;
+ case EbtBool:
+ nameSink << "bvec";
+ break;
+ case EbtUInt:
+ nameSink << "uvec";
+ break;
+ case EbtFloat:
+ nameSink << "vec";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ nameSink << static_cast<uint32_t>(type.getNominalSize());
+ }
+ return nameSink.str();
+}
+
+TIntermConstantUnion *CreateIntConstantNode(int i)
+{
+ TConstantUnion *constant = new TConstantUnion();
+ constant->setIConst(i);
+ return new TIntermConstantUnion(constant, TType(EbtInt, EbpHigh));
+}
+
+TIntermTyped *EnsureSignedInt(TIntermTyped *node)
+{
+ if (node->getBasicType() == EbtInt)
+ return node;
+
+ TIntermSequence arguments;
+ arguments.push_back(node);
+ return TIntermAggregate::CreateConstructor(TType(EbtInt), &arguments);
+}
+
+TType *GetFieldType(const TType &indexedType)
+{
+ TType *fieldType = new TType(indexedType);
+ if (indexedType.isMatrix())
+ {
+ fieldType->toMatrixColumnType();
+ }
+ else
+ {
+ ASSERT(indexedType.isVector());
+ fieldType->toComponentType();
+ }
+ // Default precision to highp if not specified. For example in |vec3(0)[i], i < 0|, there is no
+ // precision assigned to vec3(0).
+ if (fieldType->getPrecision() == EbpUndefined)
+ {
+ fieldType->setPrecision(EbpHigh);
+ }
+ return fieldType;
+}
+
+const TType *GetBaseType(const TType &type, bool write)
+{
+ TType *baseType = new TType(type);
+ // Conservatively use highp here, even if the indexed type is not highp. That way the code can't
+ // end up using mediump version of an indexing function for a highp value, if both mediump and
+ // highp values are being indexed in the shader. For HLSL precision doesn't matter, but in
+ // principle this code could be used with multiple backends.
+ baseType->setPrecision(EbpHigh);
+ baseType->setQualifier(EvqParamInOut);
+ if (!write)
+ baseType->setQualifier(EvqParamIn);
+ return baseType;
+}
+
+// Generate a read or write function for one field in a vector/matrix.
+// Out-of-range indices are clamped. This is consistent with how ANGLE handles out-of-range
+// indices in other places.
+// Note that indices can be either int or uint. We create only int versions of the functions,
+// and convert uint indices to int at the call site.
+// read function example:
+// float dyn_index_vec2(in vec2 base, in int index)
+// {
+// switch(index)
+// {
+// case (0):
+// return base[0];
+// case (1):
+// return base[1];
+// default:
+// break;
+// }
+// if (index < 0)
+// return base[0];
+// return base[1];
+// }
+// write function example:
+// void dyn_index_write_vec2(inout vec2 base, in int index, in float value)
+// {
+// switch(index)
+// {
+// case (0):
+// base[0] = value;
+// return;
+// case (1):
+// base[1] = value;
+// return;
+// default:
+// break;
+// }
+// if (index < 0)
+// {
+// base[0] = value;
+// return;
+// }
+// base[1] = value;
+// }
+// Note that else is not used in above functions to avoid the RewriteElseBlocks transformation.
+TIntermFunctionDefinition *GetIndexFunctionDefinition(const TType &type,
+ bool write,
+ const TFunction &func,
+ TSymbolTable *symbolTable)
+{
+ ASSERT(!type.isArray());
+
+ uint8_t numCases = 0;
+ if (type.isMatrix())
+ {
+ numCases = type.getCols();
+ }
+ else
+ {
+ numCases = type.getNominalSize();
+ }
+
+ std::string functionName = GetIndexFunctionName(type, write);
+ TIntermFunctionPrototype *prototypeNode = CreateInternalFunctionPrototypeNode(func);
+
+ TIntermSymbol *baseParam = new TIntermSymbol(func.getParam(0));
+ TIntermSymbol *indexParam = new TIntermSymbol(func.getParam(1));
+ TIntermSymbol *valueParam = nullptr;
+ if (write)
+ {
+ valueParam = new TIntermSymbol(func.getParam(2));
+ }
+
+ TIntermBlock *statementList = new TIntermBlock();
+ for (uint8_t i = 0; i < numCases; ++i)
+ {
+ TIntermCase *caseNode = new TIntermCase(CreateIntConstantNode(i));
+ statementList->getSequence()->push_back(caseNode);
+
+ TIntermBinary *indexNode =
+ new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(i));
+ if (write)
+ {
+ TIntermBinary *assignNode =
+ new TIntermBinary(EOpAssign, indexNode, valueParam->deepCopy());
+ statementList->getSequence()->push_back(assignNode);
+ TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr);
+ statementList->getSequence()->push_back(returnNode);
+ }
+ else
+ {
+ TIntermBranch *returnNode = new TIntermBranch(EOpReturn, indexNode);
+ statementList->getSequence()->push_back(returnNode);
+ }
+ }
+
+ // Default case
+ TIntermCase *defaultNode = new TIntermCase(nullptr);
+ statementList->getSequence()->push_back(defaultNode);
+ TIntermBranch *breakNode = new TIntermBranch(EOpBreak, nullptr);
+ statementList->getSequence()->push_back(breakNode);
+
+ TIntermSwitch *switchNode = new TIntermSwitch(indexParam->deepCopy(), statementList);
+
+ TIntermBlock *bodyNode = new TIntermBlock();
+ bodyNode->getSequence()->push_back(switchNode);
+
+ TIntermBinary *cond =
+ new TIntermBinary(EOpLessThan, indexParam->deepCopy(), CreateIntConstantNode(0));
+
+ // Two blocks: one accesses (either reads or writes) the first element and returns,
+ // the other accesses the last element.
+ TIntermBlock *useFirstBlock = new TIntermBlock();
+ TIntermBlock *useLastBlock = new TIntermBlock();
+ TIntermBinary *indexFirstNode =
+ new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(0));
+ TIntermBinary *indexLastNode =
+ new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(numCases - 1));
+ if (write)
+ {
+ TIntermBinary *assignFirstNode =
+ new TIntermBinary(EOpAssign, indexFirstNode, valueParam->deepCopy());
+ useFirstBlock->getSequence()->push_back(assignFirstNode);
+ TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr);
+ useFirstBlock->getSequence()->push_back(returnNode);
+
+ TIntermBinary *assignLastNode =
+ new TIntermBinary(EOpAssign, indexLastNode, valueParam->deepCopy());
+ useLastBlock->getSequence()->push_back(assignLastNode);
+ }
+ else
+ {
+ TIntermBranch *returnFirstNode = new TIntermBranch(EOpReturn, indexFirstNode);
+ useFirstBlock->getSequence()->push_back(returnFirstNode);
+
+ TIntermBranch *returnLastNode = new TIntermBranch(EOpReturn, indexLastNode);
+ useLastBlock->getSequence()->push_back(returnLastNode);
+ }
+ TIntermIfElse *ifNode = new TIntermIfElse(cond, useFirstBlock, nullptr);
+ bodyNode->getSequence()->push_back(ifNode);
+ bodyNode->getSequence()->push_back(useLastBlock);
+
+ TIntermFunctionDefinition *indexingFunction =
+ new TIntermFunctionDefinition(prototypeNode, bodyNode);
+ return indexingFunction;
+}
+
+class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser
+{
+ public:
+ RemoveDynamicIndexingTraverser(DynamicIndexingNodeMatcher &&matcher,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics);
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+
+ void insertHelperDefinitions(TIntermNode *root);
+
+ void nextIteration();
+
+ bool usedTreeInsertion() const { return mUsedTreeInsertion; }
+
+ protected:
+ // Maps of types that are indexed to the indexing function ids used for them. Note that these
+ // can not store multiple variants of the same type with different precisions - only one
+ // precision gets stored.
+ std::map<TType, TFunction *> mIndexedVecAndMatrixTypes;
+ std::map<TType, TFunction *> mWrittenVecAndMatrixTypes;
+
+ bool mUsedTreeInsertion;
+
+ // When true, the traverser will remove side effects from any indexing expression.
+ // This is done so that in code like
+ // V[j++][i]++.
+ // where V is an array of vectors, j++ will only be evaluated once.
+ bool mRemoveIndexSideEffectsInSubtree;
+
+ DynamicIndexingNodeMatcher mMatcher;
+ PerformanceDiagnostics *mPerfDiagnostics;
+};
+
+RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(
+ DynamicIndexingNodeMatcher &&matcher,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics)
+ : TLValueTrackingTraverser(true, false, false, symbolTable),
+ mUsedTreeInsertion(false),
+ mRemoveIndexSideEffectsInSubtree(false),
+ mMatcher(matcher),
+ mPerfDiagnostics(perfDiagnostics)
+{}
+
+void RemoveDynamicIndexingTraverser::insertHelperDefinitions(TIntermNode *root)
+{
+ TIntermBlock *rootBlock = root->getAsBlock();
+ ASSERT(rootBlock != nullptr);
+ TIntermSequence insertions;
+ for (auto &type : mIndexedVecAndMatrixTypes)
+ {
+ insertions.push_back(
+ GetIndexFunctionDefinition(type.first, false, *type.second, mSymbolTable));
+ }
+ for (auto &type : mWrittenVecAndMatrixTypes)
+ {
+ insertions.push_back(
+ GetIndexFunctionDefinition(type.first, true, *type.second, mSymbolTable));
+ }
+ rootBlock->insertChildNodes(0, insertions);
+}
+
+// Create a call to dyn_index_*() based on an indirect indexing op node
+TIntermAggregate *CreateIndexFunctionCall(TIntermBinary *node,
+ TIntermTyped *index,
+ TFunction *indexingFunction)
+{
+ ASSERT(node->getOp() == EOpIndexIndirect);
+ TIntermSequence arguments;
+ arguments.push_back(node->getLeft());
+ arguments.push_back(index);
+
+ TIntermAggregate *indexingCall =
+ TIntermAggregate::CreateFunctionCall(*indexingFunction, &arguments);
+ indexingCall->setLine(node->getLine());
+ return indexingCall;
+}
+
+TIntermAggregate *CreateIndexedWriteFunctionCall(TIntermBinary *node,
+ TVariable *index,
+ TVariable *writtenValue,
+ TFunction *indexedWriteFunction)
+{
+ ASSERT(node->getOp() == EOpIndexIndirect);
+ TIntermSequence arguments;
+ // Deep copy the child nodes so that two pointers to the same node don't end up in the tree.
+ arguments.push_back(node->getLeft()->deepCopy());
+ arguments.push_back(CreateTempSymbolNode(index));
+ arguments.push_back(CreateTempSymbolNode(writtenValue));
+
+ TIntermAggregate *indexedWriteCall =
+ TIntermAggregate::CreateFunctionCall(*indexedWriteFunction, &arguments);
+ indexedWriteCall->setLine(node->getLine());
+ return indexedWriteCall;
+}
+
+bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (mUsedTreeInsertion)
+ return false;
+
+ if (node->getOp() == EOpIndexIndirect)
+ {
+ if (mRemoveIndexSideEffectsInSubtree)
+ {
+ ASSERT(node->getRight()->hasSideEffects());
+ // In case we're just removing index side effects, convert
+ // v_expr[index_expr]
+ // to this:
+ // int s0 = index_expr; v_expr[s0];
+ // Now v_expr[s0] can be safely executed several times without unintended side effects.
+ TIntermDeclaration *indexVariableDeclaration = nullptr;
+ TVariable *indexVariable = DeclareTempVariable(mSymbolTable, node->getRight(),
+ EvqTemporary, &indexVariableDeclaration);
+ insertStatementInParentBlock(indexVariableDeclaration);
+ mUsedTreeInsertion = true;
+
+ // Replace the index with the temp variable
+ TIntermSymbol *tempIndex = CreateTempSymbolNode(indexVariable);
+ queueReplacementWithParent(node, node->getRight(), tempIndex, OriginalNode::IS_DROPPED);
+ }
+ else if (mMatcher(node))
+ {
+ if (mPerfDiagnostics)
+ {
+ mPerfDiagnostics->warning(node->getLine(),
+ "Performance: dynamic indexing of vectors and "
+ "matrices is emulated and can be slow.",
+ "[]");
+ }
+ bool write = isLValueRequiredHere();
+
+#if defined(ANGLE_ENABLE_ASSERTS)
+ // Make sure that IntermNodePatternMatcher is consistent with the slightly differently
+ // implemented checks in this traverser.
+ IntermNodePatternMatcher matcher(
+ IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue);
+ ASSERT(matcher.match(node, getParentNode(), isLValueRequiredHere()) == write);
+#endif
+
+ const TType &type = node->getLeft()->getType();
+ ImmutableString indexingFunctionName(GetIndexFunctionName(type, false));
+ TFunction *indexingFunction = nullptr;
+ if (mIndexedVecAndMatrixTypes.find(type) == mIndexedVecAndMatrixTypes.end())
+ {
+ indexingFunction =
+ new TFunction(mSymbolTable, indexingFunctionName, SymbolType::AngleInternal,
+ GetFieldType(type), true);
+ indexingFunction->addParameter(new TVariable(
+ mSymbolTable, kBaseName, GetBaseType(type, false), SymbolType::AngleInternal));
+ indexingFunction->addParameter(
+ new TVariable(mSymbolTable, kIndexName, kIndexType, SymbolType::AngleInternal));
+ mIndexedVecAndMatrixTypes[type] = indexingFunction;
+ }
+ else
+ {
+ indexingFunction = mIndexedVecAndMatrixTypes[type];
+ }
+
+ if (write)
+ {
+ // Convert:
+ // v_expr[index_expr]++;
+ // to this:
+ // int s0 = index_expr; float s1 = dyn_index(v_expr, s0); s1++;
+ // dyn_index_write(v_expr, s0, s1);
+ // This works even if index_expr has some side effects.
+ if (node->getLeft()->hasSideEffects())
+ {
+ // If v_expr has side effects, those need to be removed before proceeding.
+ // Otherwise the side effects of v_expr would be evaluated twice.
+ // The only case where an l-value can have side effects is when it is
+ // indexing. For example, it can be V[j++] where V is an array of vectors.
+ mRemoveIndexSideEffectsInSubtree = true;
+ return true;
+ }
+
+ TIntermBinary *leftBinary = node->getLeft()->getAsBinaryNode();
+ if (leftBinary != nullptr && mMatcher(leftBinary))
+ {
+ // This is a case like:
+ // mat2 m;
+ // m[a][b]++;
+ // Process the child node m[a] first.
+ return true;
+ }
+
+ // TODO(oetuaho@nvidia.com): This is not optimal if the expression using the value
+ // only writes it and doesn't need the previous value. http://anglebug.com/1116
+
+ TFunction *indexedWriteFunction = nullptr;
+ if (mWrittenVecAndMatrixTypes.find(type) == mWrittenVecAndMatrixTypes.end())
+ {
+ ImmutableString functionName(
+ GetIndexFunctionName(node->getLeft()->getType(), true));
+ indexedWriteFunction =
+ new TFunction(mSymbolTable, functionName, SymbolType::AngleInternal,
+ StaticType::GetBasic<EbtVoid, EbpUndefined>(), false);
+ indexedWriteFunction->addParameter(new TVariable(mSymbolTable, kBaseName,
+ GetBaseType(type, true),
+ SymbolType::AngleInternal));
+ indexedWriteFunction->addParameter(new TVariable(
+ mSymbolTable, kIndexName, kIndexType, SymbolType::AngleInternal));
+ TType *valueType = GetFieldType(type);
+ valueType->setQualifier(EvqParamIn);
+ indexedWriteFunction->addParameter(new TVariable(
+ mSymbolTable, kValueName, static_cast<const TType *>(valueType),
+ SymbolType::AngleInternal));
+ mWrittenVecAndMatrixTypes[type] = indexedWriteFunction;
+ }
+ else
+ {
+ indexedWriteFunction = mWrittenVecAndMatrixTypes[type];
+ }
+
+ TIntermSequence insertionsBefore;
+ TIntermSequence insertionsAfter;
+
+ // Store the index in a temporary signed int variable.
+ // s0 = index_expr;
+ TIntermTyped *indexInitializer = EnsureSignedInt(node->getRight());
+ TIntermDeclaration *indexVariableDeclaration = nullptr;
+ TVariable *indexVariable = DeclareTempVariable(
+ mSymbolTable, indexInitializer, EvqTemporary, &indexVariableDeclaration);
+ insertionsBefore.push_back(indexVariableDeclaration);
+
+ // s1 = dyn_index(v_expr, s0);
+ TIntermAggregate *indexingCall = CreateIndexFunctionCall(
+ node, CreateTempSymbolNode(indexVariable), indexingFunction);
+ TIntermDeclaration *fieldVariableDeclaration = nullptr;
+ TVariable *fieldVariable = DeclareTempVariable(
+ mSymbolTable, indexingCall, EvqTemporary, &fieldVariableDeclaration);
+ insertionsBefore.push_back(fieldVariableDeclaration);
+
+ // dyn_index_write(v_expr, s0, s1);
+ TIntermAggregate *indexedWriteCall = CreateIndexedWriteFunctionCall(
+ node, indexVariable, fieldVariable, indexedWriteFunction);
+ insertionsAfter.push_back(indexedWriteCall);
+ insertStatementsInParentBlock(insertionsBefore, insertionsAfter);
+
+ // replace the node with s1
+ queueReplacement(CreateTempSymbolNode(fieldVariable), OriginalNode::IS_DROPPED);
+ mUsedTreeInsertion = true;
+ }
+ else
+ {
+ // The indexed value is not being written, so we can simply convert
+ // v_expr[index_expr]
+ // into
+ // dyn_index(v_expr, index_expr)
+ // If the index_expr is unsigned, we'll convert it to signed.
+ ASSERT(!mRemoveIndexSideEffectsInSubtree);
+ TIntermAggregate *indexingCall = CreateIndexFunctionCall(
+ node, EnsureSignedInt(node->getRight()), indexingFunction);
+ queueReplacement(indexingCall, OriginalNode::IS_DROPPED);
+ }
+ }
+ }
+ return !mUsedTreeInsertion;
+}
+
+void RemoveDynamicIndexingTraverser::nextIteration()
+{
+ mUsedTreeInsertion = false;
+ mRemoveIndexSideEffectsInSubtree = false;
+}
+
+bool RemoveDynamicIndexingIf(DynamicIndexingNodeMatcher &&matcher,
+ TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ // This transformation adds function declarations after the fact and so some validation is
+ // momentarily disabled.
+ bool enableValidateFunctionCall = compiler->disableValidateFunctionCall();
+
+ RemoveDynamicIndexingTraverser traverser(std::move(matcher), symbolTable, perfDiagnostics);
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ } while (traverser.usedTreeInsertion());
+ // TODO(oetuaho@nvidia.com): It might be nicer to add the helper definitions also in the middle
+ // of traversal. Now the tree ends up in an inconsistent state in the middle, since there are
+ // function call nodes with no corresponding definition nodes. This needs special handling in
+ // TIntermLValueTrackingTraverser, and creates intricacies that are not easily apparent from a
+ // superficial reading of the code.
+ traverser.insertHelperDefinitions(root);
+
+ compiler->restoreValidateFunctionCall(enableValidateFunctionCall);
+ return compiler->validateAST(root);
+}
+
+} // namespace
+
+[[nodiscard]] bool RemoveDynamicIndexingOfNonSSBOVectorOrMatrix(
+ TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ DynamicIndexingNodeMatcher matcher = [](TIntermBinary *node) {
+ return IntermNodePatternMatcher::IsDynamicIndexingOfNonSSBOVectorOrMatrix(node);
+ };
+ return RemoveDynamicIndexingIf(std::move(matcher), compiler, root, symbolTable,
+ perfDiagnostics);
+}
+
+[[nodiscard]] bool RemoveDynamicIndexingOfSwizzledVector(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ DynamicIndexingNodeMatcher matcher = [](TIntermBinary *node) {
+ return IntermNodePatternMatcher::IsDynamicIndexingOfSwizzledVector(node);
+ };
+ return RemoveDynamicIndexingIf(std::move(matcher), compiler, root, symbolTable,
+ perfDiagnostics);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.h
new file mode 100644
index 0000000000..9693f55c40
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.h
@@ -0,0 +1,41 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of non-SSBO vectors and
+// matrices, replacing them with calls to functions that choose which component to return or write.
+// We don't need to consider dynamic indexing in SSBO since it can be directly as part of the offset
+// of RWByteAddressBuffer.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEDYNAMICINDEXING_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEDYNAMICINDEXING_H_
+
+#include "common/angleutils.h"
+
+#include <functional>
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TIntermBinary;
+class TSymbolTable;
+class PerformanceDiagnostics;
+
+[[nodiscard]] bool RemoveDynamicIndexingOfNonSSBOVectorOrMatrix(
+ TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics);
+
+[[nodiscard]] bool RemoveDynamicIndexingOfSwizzledVector(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEDYNAMICINDEXING_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.cpp
new file mode 100644
index 0000000000..a5e20ebcb0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.cpp
@@ -0,0 +1,209 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveInactiveInterfaceVariables.h:
+// Drop shader interface variable declarations for those that are inactive.
+//
+
+#include "compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Traverser that removes all declarations that correspond to inactive variables.
+class RemoveInactiveInterfaceVariablesTraverser : public TIntermTraverser
+{
+ public:
+ RemoveInactiveInterfaceVariablesTraverser(
+ TSymbolTable *symbolTable,
+ const std::vector<sh::ShaderVariable> &attributes,
+ const std::vector<sh::ShaderVariable> &inputVaryings,
+ const std::vector<sh::ShaderVariable> &outputVariables,
+ const std::vector<sh::ShaderVariable> &uniforms,
+ const std::vector<sh::InterfaceBlock> &interfaceBlocks,
+ bool removeFragmentOutputs);
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+
+ private:
+ const std::vector<sh::ShaderVariable> &mAttributes;
+ const std::vector<sh::ShaderVariable> &mInputVaryings;
+ const std::vector<sh::ShaderVariable> &mOutputVariables;
+ const std::vector<sh::ShaderVariable> &mUniforms;
+ const std::vector<sh::InterfaceBlock> &mInterfaceBlocks;
+ bool mRemoveFragmentOutputs;
+};
+
+RemoveInactiveInterfaceVariablesTraverser::RemoveInactiveInterfaceVariablesTraverser(
+ TSymbolTable *symbolTable,
+ const std::vector<sh::ShaderVariable> &attributes,
+ const std::vector<sh::ShaderVariable> &inputVaryings,
+ const std::vector<sh::ShaderVariable> &outputVariables,
+ const std::vector<sh::ShaderVariable> &uniforms,
+ const std::vector<sh::InterfaceBlock> &interfaceBlocks,
+ bool removeFragmentOutputs)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mAttributes(attributes),
+ mInputVaryings(inputVaryings),
+ mOutputVariables(outputVariables),
+ mUniforms(uniforms),
+ mInterfaceBlocks(interfaceBlocks),
+ mRemoveFragmentOutputs(removeFragmentOutputs)
+{}
+
+template <typename Variable>
+bool IsVariableActive(const std::vector<Variable> &mVars, const ImmutableString &name)
+{
+ for (const Variable &var : mVars)
+ {
+ if (name == var.name)
+ {
+ return var.active;
+ }
+ }
+ UNREACHABLE();
+ return true;
+}
+
+bool RemoveInactiveInterfaceVariablesTraverser::visitDeclaration(Visit visit,
+ TIntermDeclaration *node)
+{
+ // SeparateDeclarations should have already been run.
+ ASSERT(node->getSequence()->size() == 1u);
+
+ TIntermTyped *declarator = node->getSequence()->front()->getAsTyped();
+ ASSERT(declarator);
+
+ TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
+ if (!asSymbol)
+ {
+ return false;
+ }
+
+ const TType &type = declarator->getType();
+
+ // Remove all shader interface variables except outputs, i.e. uniforms, interface blocks and
+ // inputs.
+ //
+ // Imagine a situation where the VS doesn't write to a varying but the FS reads from it. This
+ // is allowed, though the value of the varying is undefined. If the varying is removed here,
+ // the situation is changed to VS not declaring the varying, but the FS reading from it, which
+ // is not allowed. That's why inactive shader outputs are not removed.
+ //
+ // Inactive fragment shader outputs can be removed though, as there is no next stage.
+ bool removeDeclaration = false;
+ const TQualifier qualifier = type.getQualifier();
+
+ if (type.isInterfaceBlock())
+ {
+ // When a member has an explicit location, interface block should not be removed.
+ // If the member or interface would be removed, GetProgramResource could not return the
+ // location.
+ if (!IsShaderIoBlock(type.getQualifier()) && type.getQualifier() != EvqPatchIn &&
+ type.getQualifier() != EvqPatchOut)
+ {
+ removeDeclaration =
+ !IsVariableActive(mInterfaceBlocks, type.getInterfaceBlock()->name());
+ }
+ }
+ else if (qualifier == EvqUniform)
+ {
+ removeDeclaration = !IsVariableActive(mUniforms, asSymbol->getName());
+ }
+ else if (qualifier == EvqAttribute || qualifier == EvqVertexIn)
+ {
+ removeDeclaration = !IsVariableActive(mAttributes, asSymbol->getName());
+ }
+ else if (IsShaderIn(qualifier))
+ {
+ removeDeclaration = !IsVariableActive(mInputVaryings, asSymbol->getName());
+ }
+ else if (qualifier == EvqFragmentOut)
+ {
+ removeDeclaration =
+ !IsVariableActive(mOutputVariables, asSymbol->getName()) && mRemoveFragmentOutputs;
+ }
+
+ if (removeDeclaration)
+ {
+ TIntermSequence replacement;
+
+ // If the declaration was of a struct, keep the struct declaration itself.
+ if (type.isStructSpecifier())
+ {
+ TType *structSpecifierType = new TType(type.getStruct(), true);
+ TVariable *emptyVariable = new TVariable(mSymbolTable, kEmptyImmutableString,
+ structSpecifierType, SymbolType::Empty);
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->appendDeclarator(new TIntermSymbol(emptyVariable));
+ replacement.push_back(declaration);
+ }
+
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(replacement));
+ }
+
+ return false;
+}
+
+bool RemoveInactiveInterfaceVariablesTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ // Remove any code that initOutputVariables might have added corresponding to inactive
+ // output variables. This code is always in the form of `variable = ...;`.
+ if (node->getOp() != EOpAssign)
+ {
+ // Don't recurse, won't find the initialization nested in another expression.
+ return false;
+ }
+
+ // Get the symbol being initialized, and check if it's an inactive output. If it is, this must
+ // necessarily be initialization code that ANGLE has added (and wasn't there in the original
+ // shader; if it was, the symbol wouldn't have been inactive).
+ TIntermSymbol *symbol = node->getLeft()->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ return false;
+ }
+
+ const TQualifier qualifier = symbol->getType().getQualifier();
+ if (qualifier != EvqFragmentOut || IsVariableActive(mOutputVariables, symbol->getName()))
+ {
+ return false;
+ }
+
+ // Drop the initialization code.
+ TIntermSequence replacement;
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node, std::move(replacement));
+ return false;
+}
+
+} // namespace
+
+bool RemoveInactiveInterfaceVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const std::vector<sh::ShaderVariable> &attributes,
+ const std::vector<sh::ShaderVariable> &inputVaryings,
+ const std::vector<sh::ShaderVariable> &outputVariables,
+ const std::vector<sh::ShaderVariable> &uniforms,
+ const std::vector<sh::InterfaceBlock> &interfaceBlocks,
+ bool removeFragmentOutputs)
+{
+ RemoveInactiveInterfaceVariablesTraverser traverser(symbolTable, attributes, inputVaryings,
+ outputVariables, uniforms, interfaceBlocks,
+ removeFragmentOutputs);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h
new file mode 100644
index 0000000000..ddbdea2ced
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h
@@ -0,0 +1,42 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveInactiveInterfaceVariables.h:
+// Drop shader interface variable declarations for those that are inactive. This step needs to be
+// done after CollectVariables. This avoids having to emulate them (e.g. atomic counters for
+// Vulkan) or remove them in glslang wrapper (again, for Vulkan).
+//
+// Shouldn't be run for the GL backend, as it queries shader interface variables from GL itself,
+// instead of relying on what was gathered during CollectVariables.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEINACTIVEVARIABLES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEINACTIVEVARIABLES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+struct InterfaceBlock;
+struct ShaderVariable;
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool RemoveInactiveInterfaceVariables(
+ TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const std::vector<sh::ShaderVariable> &attributes,
+ const std::vector<sh::ShaderVariable> &inputVaryings,
+ const std::vector<sh::ShaderVariable> &outputVariables,
+ const std::vector<sh::ShaderVariable> &uniforms,
+ const std::vector<sh::InterfaceBlock> &interfaceBlocks,
+ bool removeFragmentOutputs);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEINACTIVEVARIABLES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp
new file mode 100644
index 0000000000..5a8ca44150
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp
@@ -0,0 +1,47 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_ops/RemoveInvariantDeclaration.h"
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// An AST traverser that removes invariant declaration for input in fragment shader
+// when GLSL >= 4.20 and for output in vertex shader when GLSL < 4.2.
+class RemoveInvariantDeclarationTraverser : public TIntermTraverser
+{
+ public:
+ RemoveInvariantDeclarationTraverser() : TIntermTraverser(true, false, false) {}
+
+ private:
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override
+ {
+ if (node->isInvariant())
+ {
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(emptyReplacement));
+ }
+ return false;
+ }
+};
+
+} // anonymous namespace
+
+bool RemoveInvariantDeclaration(TCompiler *compiler, TIntermNode *root)
+{
+ RemoveInvariantDeclarationTraverser traverser;
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.h
new file mode 100644
index 0000000000..0fee87b3b1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.h
@@ -0,0 +1,21 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEINVARIANTDECLARATION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEINVARIANTDECLARATION_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+[[nodiscard]] bool RemoveInvariantDeclaration(TCompiler *compiler, TIntermNode *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEINVARIANTDECLARATION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp
new file mode 100644
index 0000000000..b87ad33633
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp
@@ -0,0 +1,371 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveUnreferencedVariables.cpp:
+// Drop variables that are declared but never referenced in the AST. This avoids adding unnecessary
+// initialization code for them. Also removes unreferenced struct types.
+//
+
+#include "compiler/translator/tree_ops/RemoveUnreferencedVariables.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class CollectVariableRefCountsTraverser : public TIntermTraverser
+{
+ public:
+ CollectVariableRefCountsTraverser();
+
+ using RefCountMap = angle::HashMap<int, unsigned int>;
+ RefCountMap &getSymbolIdRefCounts() { return mSymbolIdRefCounts; }
+ RefCountMap &getStructIdRefCounts() { return mStructIdRefCounts; }
+
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+
+ private:
+ void incrementStructTypeRefCount(const TType &type);
+
+ RefCountMap mSymbolIdRefCounts;
+
+ // Structure reference counts are counted from symbols, constructors, function calls, function
+ // return values and from interface block and structure fields. We need to track both function
+ // calls and function return values since there's a compiler option not to prune unused
+ // functions. The type of a constant union may also be a struct, but statements that are just a
+ // constant union are always pruned, and if the constant union is used somehow it will get
+ // counted by something else.
+ RefCountMap mStructIdRefCounts;
+};
+
+CollectVariableRefCountsTraverser::CollectVariableRefCountsTraverser()
+ : TIntermTraverser(true, false, false)
+{}
+
+void CollectVariableRefCountsTraverser::incrementStructTypeRefCount(const TType &type)
+{
+ if (type.isInterfaceBlock())
+ {
+ const auto *block = type.getInterfaceBlock();
+ ASSERT(block);
+
+ // We can end up incrementing ref counts of struct types referenced from an interface block
+ // multiple times for the same block. This doesn't matter, because interface blocks can't be
+ // pruned so we'll never do the reverse operation.
+ for (const auto &field : block->fields())
+ {
+ ASSERT(!field->type()->isInterfaceBlock());
+ incrementStructTypeRefCount(*field->type());
+ }
+ return;
+ }
+
+ const auto *structure = type.getStruct();
+ if (structure != nullptr)
+ {
+ auto structIter = mStructIdRefCounts.find(structure->uniqueId().get());
+ if (structIter == mStructIdRefCounts.end())
+ {
+ mStructIdRefCounts[structure->uniqueId().get()] = 1u;
+
+ for (const auto &field : structure->fields())
+ {
+ incrementStructTypeRefCount(*field->type());
+ }
+
+ return;
+ }
+ ++(structIter->second);
+ }
+}
+
+void CollectVariableRefCountsTraverser::visitSymbol(TIntermSymbol *node)
+{
+ incrementStructTypeRefCount(node->getType());
+
+ auto iter = mSymbolIdRefCounts.find(node->uniqueId().get());
+ if (iter == mSymbolIdRefCounts.end())
+ {
+ mSymbolIdRefCounts[node->uniqueId().get()] = 1u;
+ return;
+ }
+ ++(iter->second);
+}
+
+bool CollectVariableRefCountsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ // This tracks struct references in both function calls and constructors.
+ incrementStructTypeRefCount(node->getType());
+ return true;
+}
+
+void CollectVariableRefCountsTraverser::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ incrementStructTypeRefCount(node->getType());
+ size_t paramCount = node->getFunction()->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ incrementStructTypeRefCount(node->getFunction()->getParam(i)->getType());
+ }
+}
+
+// Traverser that removes all unreferenced variables on one traversal.
+class RemoveUnreferencedVariablesTraverser : public TIntermTraverser
+{
+ public:
+ RemoveUnreferencedVariablesTraverser(
+ CollectVariableRefCountsTraverser::RefCountMap *symbolIdRefCounts,
+ CollectVariableRefCountsTraverser::RefCountMap *structIdRefCounts,
+ TSymbolTable *symbolTable);
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+ // Traverse loop and block nodes in reverse order. Note that this traverser does not track
+ // parent block positions, so insertStatementInParentBlock is unusable!
+ void traverseBlock(TIntermBlock *block) override;
+ void traverseLoop(TIntermLoop *loop) override;
+
+ private:
+ void removeVariableDeclaration(TIntermDeclaration *node, TIntermTyped *declarator);
+ void decrementStructTypeRefCount(const TType &type);
+
+ CollectVariableRefCountsTraverser::RefCountMap *mSymbolIdRefCounts;
+ CollectVariableRefCountsTraverser::RefCountMap *mStructIdRefCounts;
+ bool mRemoveReferences;
+};
+
+RemoveUnreferencedVariablesTraverser::RemoveUnreferencedVariablesTraverser(
+ CollectVariableRefCountsTraverser::RefCountMap *symbolIdRefCounts,
+ CollectVariableRefCountsTraverser::RefCountMap *structIdRefCounts,
+ TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, true, symbolTable),
+ mSymbolIdRefCounts(symbolIdRefCounts),
+ mStructIdRefCounts(structIdRefCounts),
+ mRemoveReferences(false)
+{}
+
+void RemoveUnreferencedVariablesTraverser::decrementStructTypeRefCount(const TType &type)
+{
+ auto *structure = type.getStruct();
+ if (structure != nullptr)
+ {
+ ASSERT(mStructIdRefCounts->find(structure->uniqueId().get()) != mStructIdRefCounts->end());
+ unsigned int structRefCount = --(*mStructIdRefCounts)[structure->uniqueId().get()];
+
+ if (structRefCount == 0)
+ {
+ for (const auto &field : structure->fields())
+ {
+ decrementStructTypeRefCount(*field->type());
+ }
+ }
+ }
+}
+
+void RemoveUnreferencedVariablesTraverser::removeVariableDeclaration(TIntermDeclaration *node,
+ TIntermTyped *declarator)
+{
+ if (declarator->getType().isStructSpecifier() && !declarator->getType().isNamelessStruct())
+ {
+ unsigned int structId = declarator->getType().getStruct()->uniqueId().get();
+ unsigned int structRefCountInThisDeclarator = 1u;
+ if (declarator->getAsBinaryNode() &&
+ declarator->getAsBinaryNode()->getRight()->getAsAggregate())
+ {
+ ASSERT(declarator->getAsBinaryNode()->getLeft()->getType().getStruct() ==
+ declarator->getType().getStruct());
+ ASSERT(declarator->getAsBinaryNode()->getRight()->getType().getStruct() ==
+ declarator->getType().getStruct());
+ structRefCountInThisDeclarator = 2u;
+ }
+ if ((*mStructIdRefCounts)[structId] > structRefCountInThisDeclarator)
+ {
+ // If this declaration declares a named struct type that is used elsewhere, we need to
+ // keep it. We can still change the declarator though so that it doesn't declare an
+ // unreferenced variable.
+
+ // Note that since we're not removing the entire declaration, the struct's reference
+ // count will end up being one less than the correct refcount. But since the struct
+ // declaration is kept, the incorrect refcount can't cause any other problems.
+
+ if (declarator->getAsSymbolNode() &&
+ declarator->getAsSymbolNode()->variable().symbolType() == SymbolType::Empty)
+ {
+ // Already an empty declaration - nothing to do.
+ return;
+ }
+ TVariable *emptyVariable =
+ new TVariable(mSymbolTable, kEmptyImmutableString, new TType(declarator->getType()),
+ SymbolType::Empty);
+ queueReplacementWithParent(node, declarator, new TIntermSymbol(emptyVariable),
+ OriginalNode::IS_DROPPED);
+ return;
+ }
+ }
+
+ if (getParentNode()->getAsBlock())
+ {
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(emptyReplacement));
+ }
+ else
+ {
+ ASSERT(getParentNode()->getAsLoopNode());
+ queueReplacement(nullptr, OriginalNode::IS_DROPPED);
+ }
+}
+
+bool RemoveUnreferencedVariablesTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ if (visit == PreVisit)
+ {
+ // SeparateDeclarations should have already been run.
+ ASSERT(node->getSequence()->size() == 1u);
+
+ TIntermTyped *declarator = node->getSequence()->back()->getAsTyped();
+ ASSERT(declarator);
+
+ // We can only remove variables that are not a part of the shader interface.
+ TQualifier qualifier = declarator->getQualifier();
+ if (qualifier != EvqTemporary && qualifier != EvqGlobal && qualifier != EvqConst)
+ {
+ return true;
+ }
+
+ bool canRemoveVariable = false;
+ TIntermSymbol *symbolNode = declarator->getAsSymbolNode();
+ if (symbolNode != nullptr)
+ {
+ canRemoveVariable = (*mSymbolIdRefCounts)[symbolNode->uniqueId().get()] == 1u ||
+ symbolNode->variable().symbolType() == SymbolType::Empty;
+ }
+ TIntermBinary *initNode = declarator->getAsBinaryNode();
+ if (initNode != nullptr)
+ {
+ ASSERT(initNode->getLeft()->getAsSymbolNode());
+ int symbolId = initNode->getLeft()->getAsSymbolNode()->uniqueId().get();
+ canRemoveVariable =
+ (*mSymbolIdRefCounts)[symbolId] == 1u && !initNode->getRight()->hasSideEffects();
+ }
+
+ if (canRemoveVariable)
+ {
+ removeVariableDeclaration(node, declarator);
+ mRemoveReferences = true;
+ }
+ return true;
+ }
+ ASSERT(visit == PostVisit);
+ mRemoveReferences = false;
+ return true;
+}
+
+void RemoveUnreferencedVariablesTraverser::visitSymbol(TIntermSymbol *node)
+{
+ if (mRemoveReferences)
+ {
+ ASSERT(mSymbolIdRefCounts->find(node->uniqueId().get()) != mSymbolIdRefCounts->end());
+ --(*mSymbolIdRefCounts)[node->uniqueId().get()];
+
+ decrementStructTypeRefCount(node->getType());
+ }
+}
+
+bool RemoveUnreferencedVariablesTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ if (visit == PreVisit && mRemoveReferences)
+ {
+ decrementStructTypeRefCount(node->getType());
+ }
+ return true;
+}
+
+void RemoveUnreferencedVariablesTraverser::traverseBlock(TIntermBlock *node)
+{
+ // We traverse blocks in reverse order. This way reference counts can be decremented when
+ // removing initializers, and variables that become unused when initializers are removed can be
+ // removed on the same traversal.
+
+ ScopedNodeInTraversalPath addToPath(this, node);
+
+ bool visit = true;
+
+ TIntermSequence *sequence = node->getSequence();
+
+ if (preVisit)
+ visit = visitBlock(PreVisit, node);
+
+ if (visit)
+ {
+ for (auto iter = sequence->rbegin(); iter != sequence->rend(); ++iter)
+ {
+ (*iter)->traverse(this);
+ if (visit && inVisit)
+ {
+ if ((iter + 1) != sequence->rend())
+ visit = visitBlock(InVisit, node);
+ }
+ }
+ }
+
+ if (visit && postVisit)
+ visitBlock(PostVisit, node);
+}
+
+void RemoveUnreferencedVariablesTraverser::traverseLoop(TIntermLoop *node)
+{
+ // We traverse loops in reverse order as well. The loop body gets traversed before the init
+ // node.
+
+ ScopedNodeInTraversalPath addToPath(this, node);
+
+ bool visit = true;
+
+ if (preVisit)
+ visit = visitLoop(PreVisit, node);
+
+ if (visit)
+ {
+ // We don't need to traverse loop expressions or conditions since they can't be declarations
+ // in the AST (loops which have a declaration in their condition get transformed in the
+ // parsing stage).
+ ASSERT(node->getExpression() == nullptr ||
+ node->getExpression()->getAsDeclarationNode() == nullptr);
+ ASSERT(node->getCondition() == nullptr ||
+ node->getCondition()->getAsDeclarationNode() == nullptr);
+
+ if (node->getBody())
+ node->getBody()->traverse(this);
+
+ if (node->getInit())
+ node->getInit()->traverse(this);
+ }
+
+ if (visit && postVisit)
+ visitLoop(PostVisit, node);
+}
+
+} // namespace
+
+bool RemoveUnreferencedVariables(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ CollectVariableRefCountsTraverser collector;
+ root->traverse(&collector);
+ RemoveUnreferencedVariablesTraverser traverser(&collector.getSymbolIdRefCounts(),
+ &collector.getStructIdRefCounts(), symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h
new file mode 100644
index 0000000000..071d19e51e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveUnreferencedVariables.h:
+// Drop variables that are declared but never referenced in the AST. This avoids adding unnecessary
+// initialization code for them. Also removes unreferenced struct types.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEUNREFERENCEDVARIABLES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEUNREFERENCEDVARIABLES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool RemoveUnreferencedVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEUNREFERENCEDVARIABLES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.cpp
new file mode 100644
index 0000000000..bd12cd1006
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.cpp
@@ -0,0 +1,348 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteAtomicCounters: Emulate atomic counter buffers with storage buffers.
+//
+
+#include "compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+struct UniformData
+{
+ // Corresponding to an array of array of opaque uniform variable, this is the flattened variable
+ // that is replacing it.
+ const TVariable *flattened;
+ // Assume a general case of array declaration with N dimensions:
+ //
+ // uniform type u[Dn]..[D2][D1];
+ //
+ // Let's define
+ //
+ // Pn = D(n-1)*...*D2*D1
+ //
+ // In that case, we have:
+ //
+ // u[In] = ac + In*Pn
+ // u[In][I(n-1)] = ac + In*Pn + I(n-1)*P(n-1)
+ // u[In]...[Ii] = ac + In*Pn + ... + Ii*Pi
+ //
+ // This array contains Pi. Note that the like TType::mArraySizes, the last element is the
+ // outermost dimension. Element 0 is necessarily 1.
+ TVector<unsigned int> mSubArraySizes;
+};
+
+using UniformMap = angle::HashMap<const TVariable *, UniformData>;
+
+TIntermTyped *RewriteArrayOfArraySubscriptExpression(TCompiler *compiler,
+ TIntermBinary *node,
+ const UniformMap &uniformMap);
+
+// Given an expression, this traverser calculates a new expression where array of array of opaque
+// uniforms are replaced with their flattened ones. In particular, this is run on the right node of
+// EOpIndexIndirect binary nodes, so that the expression in the index gets a chance to go through
+// this transformation.
+class RewriteExpressionTraverser final : public TIntermTraverser
+{
+ public:
+ explicit RewriteExpressionTraverser(TCompiler *compiler, const UniformMap &uniformMap)
+ : TIntermTraverser(true, false, false), mCompiler(compiler), mUniformMap(uniformMap)
+ {}
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TIntermTyped *rewritten =
+ RewriteArrayOfArraySubscriptExpression(mCompiler, node, mUniformMap);
+ if (rewritten == nullptr)
+ {
+ return true;
+ }
+
+ queueReplacement(rewritten, OriginalNode::IS_DROPPED);
+
+ // Don't iterate as the expression is rewritten.
+ return false;
+ }
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ // We cannot reach here for an opaque uniform that is being replaced. visitBinary should
+ // have taken care of it.
+ ASSERT(!IsOpaqueType(node->getType().getBasicType()) ||
+ mUniformMap.find(&node->variable()) == mUniformMap.end());
+ }
+
+ private:
+ TCompiler *mCompiler;
+
+ const UniformMap &mUniformMap;
+};
+
+// Rewrite the index of an EOpIndexIndirect expression. The root can never need replacing, because
+// it cannot be an opaque uniform itself.
+void RewriteIndexExpression(TCompiler *compiler,
+ TIntermTyped *expression,
+ const UniformMap &uniformMap)
+{
+ RewriteExpressionTraverser traverser(compiler, uniformMap);
+ expression->traverse(&traverser);
+ bool valid = traverser.updateTree(compiler, expression);
+ ASSERT(valid);
+}
+
+// Given an expression such as the following:
+//
+// EOpIndex(In)Direct (opaque uniform)
+// / \
+// EOpIndex(In)Direct I1
+// / \
+// ... I2
+// /
+// EOpIndex(In)Direct
+// / \
+// uniform In
+//
+// produces:
+//
+// EOpIndex(In)Direct
+// / \
+// uniform In*Pn + ... + I2*P2 + I1*P1
+//
+TIntermTyped *RewriteArrayOfArraySubscriptExpression(TCompiler *compiler,
+ TIntermBinary *node,
+ const UniformMap &uniformMap)
+{
+ // Only interested in opaque uniforms.
+ if (!IsOpaqueType(node->getType().getBasicType()))
+ {
+ return nullptr;
+ }
+
+ TIntermSymbol *opaqueUniform = nullptr;
+
+ // Iterate once and find the opaque uniform that's being indexed.
+ TIntermBinary *iter = node;
+ while (opaqueUniform == nullptr)
+ {
+ ASSERT(iter->getOp() == EOpIndexDirect || iter->getOp() == EOpIndexIndirect);
+
+ opaqueUniform = iter->getLeft()->getAsSymbolNode();
+ iter = iter->getLeft()->getAsBinaryNode();
+ }
+
+ // If not being replaced, there's nothing to do.
+ auto flattenedIter = uniformMap.find(&opaqueUniform->variable());
+ if (flattenedIter == uniformMap.end())
+ {
+ return nullptr;
+ }
+
+ const UniformData &data = flattenedIter->second;
+
+ // Iterate again and build the index expression. The index expression constitutes the sum of
+ // the variable indices plus a constant offset calculated from the constant indices. For
+ // example, smplr[1][x][2][y] will have an index of x*P3 + y*P1 + c, where c = (1*P4 + 2*P2).
+ unsigned int constantOffset = 0;
+ TIntermTyped *variableIndex = nullptr;
+
+ // Since the opaque uniforms are fully subscripted, we know exactly how many EOpIndex* nodes
+ // there should be.
+ for (size_t dimIndex = 0; dimIndex < data.mSubArraySizes.size(); ++dimIndex)
+ {
+ ASSERT(node);
+
+ unsigned int subArraySize = data.mSubArraySizes[dimIndex];
+
+ switch (node->getOp())
+ {
+ case EOpIndexDirect:
+ // Accumulate the constant index.
+ constantOffset +=
+ node->getRight()->getAsConstantUnion()->getIConst(0) * subArraySize;
+ break;
+ case EOpIndexIndirect:
+ {
+ // Run RewriteExpressionTraverser on the right node. It may itself be an expression
+ // with an array of array of opaque uniform inside that needs to be rewritten.
+ TIntermTyped *indexExpression = node->getRight();
+ RewriteIndexExpression(compiler, indexExpression, uniformMap);
+
+ // Scale and accumulate.
+ if (subArraySize != 1)
+ {
+ indexExpression =
+ new TIntermBinary(EOpMul, indexExpression, CreateIndexNode(subArraySize));
+ }
+
+ if (variableIndex == nullptr)
+ {
+ variableIndex = indexExpression;
+ }
+ else
+ {
+ variableIndex = new TIntermBinary(EOpAdd, variableIndex, indexExpression);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ node = node->getLeft()->getAsBinaryNode();
+ }
+
+ // Add the two accumulated indices together.
+ TIntermTyped *index = nullptr;
+ if (constantOffset == 0 && variableIndex != nullptr)
+ {
+ // No constant offset, but there's variable offset. Take that as offset.
+ index = variableIndex;
+ }
+ else
+ {
+ // Either the constant offset is non zero, or there's no variable offset (so constant 0
+ // should be used).
+ index = CreateIndexNode(constantOffset);
+
+ if (variableIndex)
+ {
+ index = new TIntermBinary(EOpAdd, index, variableIndex);
+ }
+ }
+
+ // Create an index into the flattened uniform.
+ TOperator op = variableIndex ? EOpIndexIndirect : EOpIndexDirect;
+ return new TIntermBinary(op, new TIntermSymbol(data.flattened), index);
+}
+
+// Traverser that takes:
+//
+// uniform sampler/image/atomic_uint u[N][M]..
+//
+// and transforms it to:
+//
+// uniform sampler/image/atomic_uint u[N * M * ..]
+//
+// MonomorphizeUnsupportedFunctions makes it impossible for this array to be partially
+// subscripted, or passed as argument to a function unsubscripted. This means that every encounter
+// of this uniform can be expected to be fully subscripted.
+//
+class RewriteArrayOfArrayOfOpaqueUniformsTraverser : public TIntermTraverser
+{
+ public:
+ RewriteArrayOfArrayOfOpaqueUniformsTraverser(TCompiler *compiler, TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable), mCompiler(compiler)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ if (!mInGlobalScope)
+ {
+ return true;
+ }
+
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+ bool isOpaqueUniform =
+ type.getQualifier() == EvqUniform && IsOpaqueType(type.getBasicType());
+
+ // Only interested in array of array of opaque uniforms.
+ if (!isOpaqueUniform || !type.isArrayOfArrays())
+ {
+ return false;
+ }
+
+ // Opaque uniforms cannot have initializers, so the declaration must necessarily be a
+ // symbol.
+ TIntermSymbol *symbol = variable->getAsSymbolNode();
+ ASSERT(symbol != nullptr);
+
+ const TVariable *uniformVariable = &symbol->variable();
+
+ // Create an entry in the map.
+ ASSERT(mUniformMap.find(uniformVariable) == mUniformMap.end());
+ UniformData &data = mUniformMap[uniformVariable];
+
+ // Calculate the accumulated dimension products. See UniformData::mSubArraySizes.
+ const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
+ mUniformMap[uniformVariable].mSubArraySizes.resize(arraySizes.size());
+ unsigned int runningProduct = 1;
+ for (size_t dimension = 0; dimension < arraySizes.size(); ++dimension)
+ {
+ data.mSubArraySizes[dimension] = runningProduct;
+ runningProduct *= arraySizes[dimension];
+ }
+
+ // Create a replacement variable with the array flattened.
+ TType *newType = new TType(type);
+ newType->toArrayBaseType();
+ newType->makeArray(runningProduct);
+
+ data.flattened = new TVariable(mSymbolTable, uniformVariable->name(), newType,
+ uniformVariable->symbolType());
+
+ TIntermDeclaration *decl = new TIntermDeclaration;
+ decl->appendDeclarator(new TIntermSymbol(data.flattened));
+
+ queueReplacement(decl, OriginalNode::IS_DROPPED);
+ return false;
+ }
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ // As an optimization, don't bother inspecting functions if there aren't any opaque uniforms
+ // to replace.
+ return !mUniformMap.empty();
+ }
+
+ // Same implementation as in RewriteExpressionTraverser. That traverser cannot replace root.
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TIntermTyped *rewritten =
+ RewriteArrayOfArraySubscriptExpression(mCompiler, node, mUniformMap);
+ if (rewritten == nullptr)
+ {
+ return true;
+ }
+
+ queueReplacement(rewritten, OriginalNode::IS_DROPPED);
+
+ // Don't iterate as the expression is rewritten.
+ return false;
+ }
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ ASSERT(!IsOpaqueType(node->getType().getBasicType()) ||
+ mUniformMap.find(&node->variable()) == mUniformMap.end());
+ }
+
+ private:
+ TCompiler *mCompiler;
+ UniformMap mUniformMap;
+};
+} // anonymous namespace
+
+bool RewriteArrayOfArrayOfOpaqueUniforms(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ RewriteArrayOfArrayOfOpaqueUniformsTraverser traverser(compiler, symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.h
new file mode 100644
index 0000000000..859ce16dc8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2021 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteArrayOfArrayOfOpaqueUniforms: Flatten array of array of opaque uniforms. Requires
+// MonomorphizeUnsupportedFunctions and RewriteStructSamplers to have been run.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITEARRAYOFARRAYOFOPAQUEUNIFORMS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITEARRAYOFARRAYOFOPAQUEUNIFORMS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteArrayOfArrayOfOpaqueUniforms(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITEARRAYOFARRAYOFOPAQUEUNIFORMS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.cpp
new file mode 100644
index 0000000000..defc59bcc0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.cpp
@@ -0,0 +1,328 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteAtomicCounters: Emulate atomic counter buffers with storage buffers.
+//
+
+#include "compiler/translator/tree_ops/RewriteAtomicCounters.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+constexpr ImmutableString kAtomicCountersVarName = ImmutableString("atomicCounters");
+constexpr ImmutableString kAtomicCounterFieldName = ImmutableString("counters");
+
+// DeclareAtomicCountersBuffer adds a storage buffer array that's used with atomic counters.
+const TVariable *DeclareAtomicCountersBuffers(TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ // Define `uint counters[];` as the only field in the interface block.
+ TFieldList *fieldList = new TFieldList;
+ TType *counterType = new TType(EbtUInt, EbpHigh, EvqGlobal);
+ counterType->makeArray(0);
+
+ TField *countersField =
+ new TField(counterType, kAtomicCounterFieldName, TSourceLoc(), SymbolType::AngleInternal);
+
+ fieldList->push_back(countersField);
+
+ TMemoryQualifier coherentMemory = TMemoryQualifier::Create();
+ coherentMemory.coherent = true;
+
+ // There are a maximum of 8 atomic counter buffers per IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS
+ // in libANGLE/Constants.h.
+ constexpr uint32_t kMaxAtomicCounterBuffers = 8;
+
+ // Define a storage block "ANGLEAtomicCounters" with instance name "atomicCounters".
+ TLayoutQualifier layoutQualifier = TLayoutQualifier::Create();
+ layoutQualifier.blockStorage = EbsStd430;
+
+ return DeclareInterfaceBlock(root, symbolTable, fieldList, EvqBuffer, layoutQualifier,
+ coherentMemory, kMaxAtomicCounterBuffers,
+ ImmutableString(vk::kAtomicCountersBlockName),
+ kAtomicCountersVarName);
+}
+
+TIntermTyped *CreateUniformBufferOffset(const TIntermTyped *uniformBufferOffsets, int binding)
+{
+ // Each uint in the |acbBufferOffsets| uniform contains offsets for 4 bindings. Therefore, the
+ // expression to get the uniform offset for the binding is:
+ //
+ // acbBufferOffsets[binding / 4] >> ((binding % 4) * 8) & 0xFF
+
+ // acbBufferOffsets[binding / 4]
+ TIntermBinary *uniformBufferOffsetUint = new TIntermBinary(
+ EOpIndexDirect, uniformBufferOffsets->deepCopy(), CreateIndexNode(binding / 4));
+
+ // acbBufferOffsets[binding / 4] >> ((binding % 4) * 8)
+ TIntermBinary *uniformBufferOffsetShifted = uniformBufferOffsetUint;
+ if (binding % 4 != 0)
+ {
+ uniformBufferOffsetShifted = new TIntermBinary(EOpBitShiftRight, uniformBufferOffsetUint,
+ CreateUIntNode((binding % 4) * 8));
+ }
+
+ // acbBufferOffsets[binding / 4] >> ((binding % 4) * 8) & 0xFF
+ return new TIntermBinary(EOpBitwiseAnd, uniformBufferOffsetShifted, CreateUIntNode(0xFF));
+}
+
+TIntermBinary *CreateAtomicCounterRef(TIntermTyped *atomicCounterExpression,
+ const TVariable *atomicCounters,
+ const TIntermTyped *uniformBufferOffsets)
+{
+ // The atomic counters storage buffer declaration looks as such:
+ //
+ // layout(...) buffer ANGLEAtomicCounters
+ // {
+ // uint counters[];
+ // } atomicCounters[N];
+ //
+ // Where N is large enough to accommodate atomic counter buffer bindings used in the shader.
+ //
+ // This function takes an expression that uses an atomic counter, which can either be:
+ //
+ // - ac
+ // - acArray[index]
+ //
+ // Note that RewriteArrayOfArrayOfOpaqueUniforms has already flattened array of array of atomic
+ // counters.
+ //
+ // For the first case (ac), the following code is generated:
+ //
+ // atomicCounters[binding].counters[offset]
+ //
+ // For the second case (acArray[index]), the following code is generated:
+ //
+ // atomicCounters[binding].counters[offset + index]
+ //
+ // In either case, an offset given through uniforms is also added to |offset|. The binding is
+ // necessarily a constant thanks to MonomorphizeUnsupportedFunctions.
+
+ // First determine if there's an index, and extract the atomic counter symbol out of the
+ // expression.
+ TIntermSymbol *atomicCounterSymbol = atomicCounterExpression->getAsSymbolNode();
+ TIntermTyped *atomicCounterIndex = nullptr;
+ int atomicCounterConstIndex = 0;
+ TIntermBinary *asBinary = atomicCounterExpression->getAsBinaryNode();
+ if (asBinary != nullptr)
+ {
+ atomicCounterSymbol = asBinary->getLeft()->getAsSymbolNode();
+
+ switch (asBinary->getOp())
+ {
+ case EOpIndexDirect:
+ atomicCounterConstIndex = asBinary->getRight()->getAsConstantUnion()->getIConst(0);
+ break;
+ case EOpIndexIndirect:
+ atomicCounterIndex = asBinary->getRight();
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ // Extract binding and offset information out of the atomic counter symbol.
+ ASSERT(atomicCounterSymbol);
+ const TVariable *atomicCounterVar = &atomicCounterSymbol->variable();
+ const TType &atomicCounterType = atomicCounterVar->getType();
+
+ const int binding = atomicCounterType.getLayoutQualifier().binding;
+ int offset = atomicCounterType.getLayoutQualifier().offset / 4;
+
+ // Create the expression:
+ //
+ // offset + arrayIndex + uniformOffset
+ //
+ // If arrayIndex is a constant, it's added with offset right here.
+
+ offset += atomicCounterConstIndex;
+
+ TIntermTyped *index = CreateUniformBufferOffset(uniformBufferOffsets, binding);
+ if (atomicCounterIndex != nullptr)
+ {
+ index = new TIntermBinary(EOpAdd, index, atomicCounterIndex);
+ }
+ if (offset != 0)
+ {
+ index = new TIntermBinary(EOpAdd, index, CreateIndexNode(offset));
+ }
+
+ // Finally, create the complete expression:
+ //
+ // atomicCounters[binding].counters[index]
+
+ TIntermSymbol *atomicCountersRef = new TIntermSymbol(atomicCounters);
+
+ // atomicCounters[binding]
+ TIntermBinary *countersBlock =
+ new TIntermBinary(EOpIndexDirect, atomicCountersRef, CreateIndexNode(binding));
+
+ // atomicCounters[binding].counters
+ TIntermBinary *counters =
+ new TIntermBinary(EOpIndexDirectInterfaceBlock, countersBlock, CreateIndexNode(0));
+
+ return new TIntermBinary(EOpIndexIndirect, counters, index);
+}
+
+// Traverser that:
+//
+// 1. Removes the |uniform atomic_uint| declarations and remembers the binding and offset.
+// 2. Substitutes |atomicVar[n]| with |buffer[binding].counters[offset + n]|.
+class RewriteAtomicCountersTraverser : public TIntermTraverser
+{
+ public:
+ RewriteAtomicCountersTraverser(TSymbolTable *symbolTable,
+ const TVariable *atomicCounters,
+ const TIntermTyped *acbBufferOffsets)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mAtomicCounters(atomicCounters),
+ mAcbBufferOffsets(acbBufferOffsets)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ if (!mInGlobalScope)
+ {
+ return true;
+ }
+
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+ bool isAtomicCounter = type.isAtomicCounter();
+
+ if (isAtomicCounter)
+ {
+ ASSERT(type.getQualifier() == EvqUniform);
+ TIntermSequence emptySequence;
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(emptySequence));
+
+ return false;
+ }
+
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (BuiltInGroup::IsBuiltIn(node->getOp()))
+ {
+ bool converted = convertBuiltinFunction(node);
+ return !converted;
+ }
+
+ // AST functions don't require modification as atomic counter function parameters are
+ // removed by MonomorphizeUnsupportedFunctions.
+ return true;
+ }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ // Cannot encounter the atomic counter symbol directly. It can only be used with functions,
+ // and therefore it's handled by visitAggregate.
+ ASSERT(!symbol->getType().isAtomicCounter());
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ // Cannot encounter an atomic counter expression directly. It can only be used with
+ // functions, and therefore it's handled by visitAggregate.
+ ASSERT(!node->getType().isAtomicCounter());
+ return true;
+ }
+
+ private:
+ bool convertBuiltinFunction(TIntermAggregate *node)
+ {
+ const TOperator op = node->getOp();
+
+ // If the function is |memoryBarrierAtomicCounter|, simply replace it with
+ // |memoryBarrierBuffer|.
+ if (op == EOpMemoryBarrierAtomicCounter)
+ {
+ TIntermSequence emptySequence;
+ TIntermTyped *substituteCall = CreateBuiltInFunctionCallNode(
+ "memoryBarrierBuffer", &emptySequence, *mSymbolTable, 310);
+ queueReplacement(substituteCall, OriginalNode::IS_DROPPED);
+ return true;
+ }
+
+ // If it's an |atomicCounter*| function, replace the function with an |atomic*| equivalent.
+ if (!node->getFunction()->isAtomicCounterFunction())
+ {
+ return false;
+ }
+
+ // Note: atomicAdd(0) is used for atomic reads.
+ uint32_t valueChange = 0;
+ constexpr char kAtomicAddFunction[] = "atomicAdd";
+ bool isDecrement = false;
+
+ if (op == EOpAtomicCounterIncrement)
+ {
+ valueChange = 1;
+ }
+ else if (op == EOpAtomicCounterDecrement)
+ {
+ // uint values are required to wrap around, so 0xFFFFFFFFu is used as -1.
+ valueChange = std::numeric_limits<uint32_t>::max();
+ static_assert(static_cast<uint32_t>(-1) == std::numeric_limits<uint32_t>::max(),
+ "uint32_t max is not -1");
+
+ isDecrement = true;
+ }
+ else
+ {
+ ASSERT(op == EOpAtomicCounter);
+ }
+
+ TIntermTyped *param = (*node->getSequence())[0]->getAsTyped();
+
+ TIntermSequence substituteArguments;
+ substituteArguments.push_back(
+ CreateAtomicCounterRef(param, mAtomicCounters, mAcbBufferOffsets));
+ substituteArguments.push_back(CreateUIntNode(valueChange));
+
+ TIntermTyped *substituteCall = CreateBuiltInFunctionCallNode(
+ kAtomicAddFunction, &substituteArguments, *mSymbolTable, 310);
+
+ // Note that atomicCounterDecrement returns the *new* value instead of the prior value,
+ // unlike atomicAdd. So we need to do a -1 on the result as well.
+ if (isDecrement)
+ {
+ substituteCall = new TIntermBinary(EOpSub, substituteCall, CreateUIntNode(1));
+ }
+
+ queueReplacement(substituteCall, OriginalNode::IS_DROPPED);
+ return true;
+ }
+
+ const TVariable *mAtomicCounters;
+ const TIntermTyped *mAcbBufferOffsets;
+};
+
+} // anonymous namespace
+
+bool RewriteAtomicCounters(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TIntermTyped *acbBufferOffsets)
+{
+ const TVariable *atomicCounters = DeclareAtomicCountersBuffers(root, symbolTable);
+
+ RewriteAtomicCountersTraverser traverser(symbolTable, atomicCounters, acbBufferOffsets);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.h
new file mode 100644
index 0000000000..8a94f84b3a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteAtomicCounters: Change atomic counter buffers to storage buffers, with atomic counter
+// variables being offsets into the uint array of that storage buffer.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITEATOMICCOUNTERS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITEATOMICCOUNTERS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TIntermTyped;
+class TSymbolTable;
+class TVariable;
+
+[[nodiscard]] bool RewriteAtomicCounters(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TIntermTyped *acbBufferOffsets);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITEATOMICCOUNTERS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.cpp
new file mode 100644
index 0000000000..f7e5814361
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.cpp
@@ -0,0 +1,984 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteCubeMapSamplersAs2DArray: Change samplerCube samplers to sampler2DArray for seamful cube
+// map emulation.
+//
+// Relies on MonomorphizeUnsupportedFunctions to ensure samplerCube variables are not
+// passed to functions (for simplicity).
+//
+
+#include "compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+constexpr ImmutableString kCoordTransformFuncName("ANGLECubeMapCoordTransform");
+constexpr ImmutableString kCoordTransformFuncNameImplicit("ANGLECubeMapCoordTransformImplicit");
+
+TIntermTyped *DerivativeQuotient(TIntermTyped *u,
+ TIntermTyped *du,
+ TIntermTyped *v,
+ TIntermTyped *dv,
+ TIntermTyped *vRecip)
+{
+ // (du v - dv u) / v^2
+ return new TIntermBinary(
+ EOpMul,
+ new TIntermBinary(EOpSub, new TIntermBinary(EOpMul, du->deepCopy(), v->deepCopy()),
+ new TIntermBinary(EOpMul, dv->deepCopy(), u->deepCopy())),
+ new TIntermBinary(EOpMul, vRecip->deepCopy(), vRecip->deepCopy()));
+}
+
+TIntermTyped *Swizzle1(TIntermTyped *array, int i)
+{
+ return new TIntermSwizzle(array, {i});
+}
+
+TIntermTyped *IndexDirect(TIntermTyped *array, int i)
+{
+ return new TIntermBinary(EOpIndexDirect, array, CreateIndexNode(i));
+}
+
+// Generated the common transformation in each coord transformation case. See comment in
+// declareCoordTranslationFunction(). Called with P, dPdx and dPdy.
+void TransformXMajor(const TSymbolTable &symbolTable,
+ TIntermBlock *block,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *uc,
+ TIntermTyped *vc)
+{
+ // uc = -sign(x)*z
+ // vc = -y
+ TIntermTyped *signX =
+ CreateBuiltInUnaryFunctionCallNode("sign", x->deepCopy(), symbolTable, 100);
+
+ TIntermTyped *ucValue =
+ new TIntermUnary(EOpNegative, new TIntermBinary(EOpMul, signX, z->deepCopy()), nullptr);
+ TIntermTyped *vcValue = new TIntermUnary(EOpNegative, y->deepCopy(), nullptr);
+
+ block->appendStatement(new TIntermBinary(EOpAssign, uc->deepCopy(), ucValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, vc->deepCopy(), vcValue));
+}
+
+void TransformDerivativeXMajor(TIntermBlock *block,
+ TSymbolTable *symbolTable,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *dx,
+ TIntermTyped *dy,
+ TIntermTyped *dz,
+ TIntermTyped *du,
+ TIntermTyped *dv,
+ TIntermTyped *xRecip)
+{
+ // Only the magnitude of the derivative matters, so we ignore the sign(x)
+ // and the negations.
+ TIntermTyped *duValue = DerivativeQuotient(z, dz, x, dx, xRecip);
+ TIntermTyped *dvValue = DerivativeQuotient(y, dy, x, dx, xRecip);
+ duValue = new TIntermBinary(EOpMul, duValue, CreateFloatNode(0.5f, EbpMedium));
+ dvValue = new TIntermBinary(EOpMul, dvValue, CreateFloatNode(0.5f, EbpMedium));
+ block->appendStatement(new TIntermBinary(EOpAssign, du->deepCopy(), duValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, dv->deepCopy(), dvValue));
+}
+
+void TransformImplicitDerivativeXMajor(TIntermBlock *block,
+ TIntermTyped *dOuter,
+ TIntermTyped *du,
+ TIntermTyped *dv)
+{
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, du->deepCopy(), Swizzle1(dOuter->deepCopy(), 2)));
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, dv->deepCopy(), Swizzle1(dOuter->deepCopy(), 1)));
+}
+
+void TransformYMajor(const TSymbolTable &symbolTable,
+ TIntermBlock *block,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *uc,
+ TIntermTyped *vc)
+{
+ // uc = x
+ // vc = sign(y)*z
+ TIntermTyped *signY =
+ CreateBuiltInUnaryFunctionCallNode("sign", y->deepCopy(), symbolTable, 100);
+
+ TIntermTyped *ucValue = x->deepCopy();
+ TIntermTyped *vcValue = new TIntermBinary(EOpMul, signY, z->deepCopy());
+
+ block->appendStatement(new TIntermBinary(EOpAssign, uc->deepCopy(), ucValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, vc->deepCopy(), vcValue));
+}
+
+void TransformDerivativeYMajor(TIntermBlock *block,
+ TSymbolTable *symbolTable,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *dx,
+ TIntermTyped *dy,
+ TIntermTyped *dz,
+ TIntermTyped *du,
+ TIntermTyped *dv,
+ TIntermTyped *yRecip)
+{
+ // Only the magnitude of the derivative matters, so we ignore the sign(x)
+ // and the negations.
+ TIntermTyped *duValue = DerivativeQuotient(x, dx, y, dy, yRecip);
+ TIntermTyped *dvValue = DerivativeQuotient(z, dz, y, dy, yRecip);
+ duValue = new TIntermBinary(EOpMul, duValue, CreateFloatNode(0.5f, EbpMedium));
+ dvValue = new TIntermBinary(EOpMul, dvValue, CreateFloatNode(0.5f, EbpMedium));
+ block->appendStatement(new TIntermBinary(EOpAssign, du->deepCopy(), duValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, dv->deepCopy(), dvValue));
+}
+
+void TransformImplicitDerivativeYMajor(TIntermBlock *block,
+ TIntermTyped *dOuter,
+ TIntermTyped *du,
+ TIntermTyped *dv)
+{
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, du->deepCopy(), Swizzle1(dOuter->deepCopy(), 0)));
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, dv->deepCopy(), Swizzle1(dOuter->deepCopy(), 2)));
+}
+
+void TransformZMajor(const TSymbolTable &symbolTable,
+ TIntermBlock *block,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *uc,
+ TIntermTyped *vc)
+{
+ // uc = size(z)*x
+ // vc = -y
+ TIntermTyped *signZ =
+ CreateBuiltInUnaryFunctionCallNode("sign", z->deepCopy(), symbolTable, 100);
+
+ TIntermTyped *ucValue = new TIntermBinary(EOpMul, signZ, x->deepCopy());
+ TIntermTyped *vcValue = new TIntermUnary(EOpNegative, y->deepCopy(), nullptr);
+
+ block->appendStatement(new TIntermBinary(EOpAssign, uc->deepCopy(), ucValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, vc->deepCopy(), vcValue));
+}
+
+void TransformDerivativeZMajor(TIntermBlock *block,
+ TSymbolTable *symbolTable,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *dx,
+ TIntermTyped *dy,
+ TIntermTyped *dz,
+ TIntermTyped *du,
+ TIntermTyped *dv,
+ TIntermTyped *zRecip)
+{
+ // Only the magnitude of the derivative matters, so we ignore the sign(x)
+ // and the negations.
+ TIntermTyped *duValue = DerivativeQuotient(x, dx, z, dz, zRecip);
+ TIntermTyped *dvValue = DerivativeQuotient(y, dy, z, dz, zRecip);
+ duValue = new TIntermBinary(EOpMul, duValue, CreateFloatNode(0.5f, EbpMedium));
+ dvValue = new TIntermBinary(EOpMul, dvValue, CreateFloatNode(0.5f, EbpMedium));
+ block->appendStatement(new TIntermBinary(EOpAssign, du->deepCopy(), duValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, dv->deepCopy(), dvValue));
+}
+
+void TransformImplicitDerivativeZMajor(TIntermBlock *block,
+ TIntermTyped *dOuter,
+ TIntermTyped *du,
+ TIntermTyped *dv)
+{
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, du->deepCopy(), Swizzle1(dOuter->deepCopy(), 0)));
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, dv->deepCopy(), Swizzle1(dOuter->deepCopy(), 1)));
+}
+
+class RewriteCubeMapSamplersAs2DArrayTraverser : public TIntermTraverser
+{
+ public:
+ RewriteCubeMapSamplersAs2DArrayTraverser(TSymbolTable *symbolTable, bool isFragmentShader)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mCubeXYZToArrayUVL(nullptr),
+ mCubeXYZToArrayUVLImplicit(nullptr),
+ mIsFragmentShader(isFragmentShader),
+ mCoordTranslationFunctionDecl(nullptr),
+ mCoordTranslationFunctionImplicitDecl(nullptr)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+ bool isSamplerCube = type.getQualifier() == EvqUniform && type.isSamplerCube();
+
+ if (isSamplerCube)
+ {
+ // Samplers cannot have initializers, so the declaration must necessarily be a symbol.
+ TIntermSymbol *samplerVariable = variable->getAsSymbolNode();
+ ASSERT(samplerVariable != nullptr);
+
+ declareSampler2DArray(&samplerVariable->variable(), node);
+ return false;
+ }
+
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (BuiltInGroup::IsBuiltIn(node->getOp()))
+ {
+ bool converted = convertBuiltinFunction(node);
+ return !converted;
+ }
+
+ // AST functions don't require modification as samplerCube function parameters are removed
+ // by MonomorphizeUnsupportedFunctions.
+ return true;
+ }
+
+ TIntermFunctionDefinition *getCoordTranslationFunctionDecl()
+ {
+ return mCoordTranslationFunctionDecl;
+ }
+
+ TIntermFunctionDefinition *getCoordTranslationFunctionDeclImplicit()
+ {
+ return mCoordTranslationFunctionImplicitDecl;
+ }
+
+ private:
+ void declareSampler2DArray(const TVariable *samplerCubeVar, TIntermDeclaration *node)
+ {
+ if (mCubeXYZToArrayUVL == nullptr)
+ {
+ // If not done yet, declare the function that transforms cube map texture sampling
+ // coordinates to face index and uv coordinates.
+ declareCoordTranslationFunction(false, kCoordTransformFuncName, &mCubeXYZToArrayUVL,
+ &mCoordTranslationFunctionDecl);
+ }
+ if (mCubeXYZToArrayUVLImplicit == nullptr && mIsFragmentShader)
+ {
+ declareCoordTranslationFunction(true, kCoordTransformFuncNameImplicit,
+ &mCubeXYZToArrayUVLImplicit,
+ &mCoordTranslationFunctionImplicitDecl);
+ }
+
+ TType *newType = new TType(samplerCubeVar->getType());
+ newType->setBasicType(EbtSampler2DArray);
+
+ TVariable *sampler2DArrayVar = new TVariable(mSymbolTable, samplerCubeVar->name(), newType,
+ samplerCubeVar->symbolType());
+
+ TIntermDeclaration *sampler2DArrayDecl = new TIntermDeclaration();
+ sampler2DArrayDecl->appendDeclarator(new TIntermSymbol(sampler2DArrayVar));
+
+ queueReplacement(sampler2DArrayDecl, OriginalNode::IS_DROPPED);
+
+ // Remember the sampler2DArray variable.
+ mSamplerMap[samplerCubeVar] = sampler2DArrayVar;
+ }
+
+ void declareCoordTranslationFunction(bool implicit,
+ const ImmutableString &name,
+ TFunction **functionOut,
+ TIntermFunctionDefinition **declOut)
+ {
+ // GLES2.0 (as well as desktop OpenGL 2.0) define the coordination transformation as
+ // follows. Given xyz cube coordinates, where each channel is in [-1, 1], the following
+ // table calculates uc, vc and ma as well as the cube map face.
+ //
+ // Major Axis Direction Target uc vc ma
+ // +x TEXTURE_CUBE_MAP_POSITIVE_X -z -y |x|
+ // -x TEXTURE_CUBE_MAP_NEGATIVE_X z -y |x|
+ // +y TEXTURE_CUBE_MAP_POSITIVE_Y x z |y|
+ // -y TEXTURE_CUBE_MAP_NEGATIVE_Y x -z |y|
+ // +z TEXTURE_CUBE_MAP_POSITIVE_Z x -y |z|
+ // -z TEXTURE_CUBE_MAP_NEGATIVE_Z -x -y |z|
+ //
+ // "Major" is an indication of the axis with the largest value. The cube map face indicates
+ // the layer to sample from. The uv coordinates to sample from are calculated as,
+ // effectively transforming the uv values to [0, 1]:
+ //
+ // u = (1 + uc/ma) / 2
+ // v = (1 + vc/ma) / 2
+ //
+ // The function can be implemented as 6 ifs, though it would be far from efficient. The
+ // following calculations implement the table above in a smaller number of instructions.
+ //
+ // First, ma can be calculated as the max of the three axes.
+ //
+ // ma = max3(|x|, |y|, |z|)
+ //
+ // We have three cases:
+ //
+ // ma == |x|: uc = -sign(x)*z
+ // vc = -y
+ // layer = float(x < 0)
+ //
+ // ma == |y|: uc = x
+ // vc = sign(y)*z
+ // layer = 2 + float(y < 0)
+ //
+ // ma == |z|: uc = size(z)*x
+ // vc = -y
+ // layer = 4 + float(z < 0)
+ //
+ // This can be implemented with a number of ?: instructions or 3 ifs. ?: would require all
+ // expressions to be evaluated (vector ALU) while if would require exec mask and jumps
+ // (scalar operations). We implement this using ifs as there would otherwise be many vector
+ // operations and not much of anything else.
+ //
+ // If textureCubeGrad is used, we also need to transform the provided dPdx and dPdy (both
+ // vec3) to a dUVdx and dUVdy. Assume P=(r,s,t) and we are investigating dx (note the
+ // change from xyz to rst to not confuse with dx and dy):
+ //
+ // uv = (f(r,s,t)/ma + 1)/2
+ //
+ // Where f is one of the transformations above for uc and vc. Between two neighbors along
+ // the x axis, we have P0=(r0,s0,t0) and P1=(r1,s1,t1)
+ //
+ // dP = (r1-r0, s1-s0, t1-t0)
+ // dUV = (f(r1,s1,t1)/ma1 - g(r0,s0,t0)/ma0) / 2
+ //
+ // f and g may not necessarily be the same because the two points may have different major
+ // axes. Even with the same major access, the sign that's used in the formulas may not be
+ // the same. Furthermore, ma0 and ma1 may not be the same. This makes it impossible to
+ // derive dUV from dP exactly.
+ //
+ // However, gradient transformation is implementation dependant, so we will simplify and
+ // assume all the above complications are non-existent. We therefore have:
+ //
+ // dUV = (f(r1,s1,t1)/ma0 - f(r0,s0,t0)/ma0)/2
+ //
+ // Given that we assumed the sign functions are returning identical results for the two
+ // points, f becomes a linear transformation. Thus:
+ //
+ // dUV = f(r1-r0,s1-0,t1-t0)/ma0/2
+ //
+ // In other words, we use the same formulae that transform XYZ (RST here) to UV to
+ // transform the derivatives.
+ //
+ // ma == |x|: dUdx = -sign(x)*dPdx.z / ma / 2
+ // dVdx = -dPdx.y / ma / 2
+ //
+ // ma == |y|: dUdx = dPdx.x / ma / 2
+ // dVdx = sign(y)*dPdx.z / ma / 2
+ //
+ // ma == |z|: dUdx = size(z)*dPdx.x / ma / 2
+ // dVdx = -dPdx.y / ma / 2
+ //
+ // Similarly for dy.
+
+ // Create the function parameters: vec3 P, vec3 dPdx, vec3 dPdy,
+ // out vec2 dUVdx, out vec2 dUVdy
+ const TType *vec3Type = StaticType::GetBasic<EbtFloat, EbpHigh, 3>();
+ TType *inVec3Type = new TType(*vec3Type);
+ inVec3Type->setQualifier(EvqParamIn);
+
+ TVariable *pVar = new TVariable(mSymbolTable, ImmutableString("P"), inVec3Type,
+ SymbolType::AngleInternal);
+ TVariable *dPdxVar = new TVariable(mSymbolTable, ImmutableString("dPdx"), inVec3Type,
+ SymbolType::AngleInternal);
+ TVariable *dPdyVar = new TVariable(mSymbolTable, ImmutableString("dPdy"), inVec3Type,
+ SymbolType::AngleInternal);
+
+ const TType *vec2Type = StaticType::GetBasic<EbtFloat, EbpHigh, 2>();
+ TType *outVec2Type = new TType(*vec2Type);
+ outVec2Type->setQualifier(EvqParamOut);
+
+ TVariable *dUVdxVar = new TVariable(mSymbolTable, ImmutableString("dUVdx"), outVec2Type,
+ SymbolType::AngleInternal);
+ TVariable *dUVdyVar = new TVariable(mSymbolTable, ImmutableString("dUVdy"), outVec2Type,
+ SymbolType::AngleInternal);
+
+ TIntermSymbol *p = new TIntermSymbol(pVar);
+ TIntermSymbol *dPdx = new TIntermSymbol(dPdxVar);
+ TIntermSymbol *dPdy = new TIntermSymbol(dPdyVar);
+ TIntermSymbol *dUVdx = new TIntermSymbol(dUVdxVar);
+ TIntermSymbol *dUVdy = new TIntermSymbol(dUVdyVar);
+
+ // Create the function body as statements are generated.
+ TIntermBlock *body = new TIntermBlock;
+
+ // Create the swizzle nodes that will be used in multiple expressions:
+ TIntermSwizzle *x = new TIntermSwizzle(p->deepCopy(), {0});
+ TIntermSwizzle *y = new TIntermSwizzle(p->deepCopy(), {1});
+ TIntermSwizzle *z = new TIntermSwizzle(p->deepCopy(), {2});
+
+ // Create abs and "< 0" expressions from the channels.
+ const TType *floatType = StaticType::GetBasic<EbtFloat, EbpHigh>();
+
+ TIntermTyped *isNegX = new TIntermBinary(EOpLessThan, x, CreateZeroNode(*floatType));
+ TIntermTyped *isNegY = new TIntermBinary(EOpLessThan, y, CreateZeroNode(*floatType));
+ TIntermTyped *isNegZ = new TIntermBinary(EOpLessThan, z, CreateZeroNode(*floatType));
+
+ TIntermSymbol *absX = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *absY = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *absZ = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+
+ TIntermDeclaration *absXDecl = CreateTempInitDeclarationNode(
+ &absX->variable(),
+ CreateBuiltInUnaryFunctionCallNode("abs", x->deepCopy(), *mSymbolTable, 100));
+ TIntermDeclaration *absYDecl = CreateTempInitDeclarationNode(
+ &absY->variable(),
+ CreateBuiltInUnaryFunctionCallNode("abs", y->deepCopy(), *mSymbolTable, 100));
+ TIntermDeclaration *absZDecl = CreateTempInitDeclarationNode(
+ &absZ->variable(),
+ CreateBuiltInUnaryFunctionCallNode("abs", z->deepCopy(), *mSymbolTable, 100));
+
+ body->appendStatement(absXDecl);
+ body->appendStatement(absYDecl);
+ body->appendStatement(absZDecl);
+
+ // Create temporary variable for division outer product matrix and its
+ // derivatives.
+ // recipOuter[i][j] = 0.5 * P[j] / P[i]
+ const TType *mat3Type = StaticType::GetBasic<EbtFloat, EbpHigh, 3, 3>();
+ TIntermSymbol *recipOuter = new TIntermSymbol(CreateTempVariable(mSymbolTable, mat3Type));
+
+ TIntermTyped *pRecip =
+ new TIntermBinary(EOpDiv, CreateFloatNode(1.0, EbpMedium), p->deepCopy());
+ TIntermSymbol *pRecipVar = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+
+ body->appendStatement(CreateTempInitDeclarationNode(&pRecipVar->variable(), pRecip));
+
+ TIntermSequence args = {
+ p->deepCopy(), new TIntermBinary(EOpVectorTimesScalar, CreateFloatNode(0.5, EbpMedium),
+ pRecipVar->deepCopy())};
+ TIntermDeclaration *recipOuterDecl = CreateTempInitDeclarationNode(
+ &recipOuter->variable(),
+ CreateBuiltInFunctionCallNode("outerProduct", &args, *mSymbolTable, 300));
+ body->appendStatement(recipOuterDecl);
+
+ TIntermSymbol *dPDXdx = nullptr;
+ TIntermSymbol *dPDYdx = nullptr;
+ TIntermSymbol *dPDZdx = nullptr;
+ TIntermSymbol *dPDXdy = nullptr;
+ TIntermSymbol *dPDYdy = nullptr;
+ TIntermSymbol *dPDZdy = nullptr;
+ if (implicit)
+ {
+ dPDXdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ dPDYdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ dPDZdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ dPDXdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ dPDYdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ dPDZdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+
+ TIntermDeclaration *dPDXdxDecl = CreateTempInitDeclarationNode(
+ &dPDXdx->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdx", IndexDirect(recipOuter, 0)->deepCopy(),
+ *mSymbolTable, 300));
+ TIntermDeclaration *dPDYdxDecl = CreateTempInitDeclarationNode(
+ &dPDYdx->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdx", IndexDirect(recipOuter, 1)->deepCopy(),
+ *mSymbolTable, 300));
+ TIntermDeclaration *dPDZdxDecl = CreateTempInitDeclarationNode(
+ &dPDZdx->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdx", IndexDirect(recipOuter, 2)->deepCopy(),
+ *mSymbolTable, 300));
+ TIntermDeclaration *dPDXdyDecl = CreateTempInitDeclarationNode(
+ &dPDXdy->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdy", IndexDirect(recipOuter, 0)->deepCopy(),
+ *mSymbolTable, 300));
+ TIntermDeclaration *dPDYdyDecl = CreateTempInitDeclarationNode(
+ &dPDYdy->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdy", IndexDirect(recipOuter, 1)->deepCopy(),
+ *mSymbolTable, 300));
+ TIntermDeclaration *dPDZdyDecl = CreateTempInitDeclarationNode(
+ &dPDZdy->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdy", IndexDirect(recipOuter, 2)->deepCopy(),
+ *mSymbolTable, 300));
+
+ body->appendStatement(dPDXdxDecl);
+ body->appendStatement(dPDYdxDecl);
+ body->appendStatement(dPDZdxDecl);
+ body->appendStatement(dPDXdyDecl);
+ body->appendStatement(dPDYdyDecl);
+ body->appendStatement(dPDZdyDecl);
+ }
+
+ // Create temporary variables for ma, uc, vc, and l (layer), as well as dUdx, dVdx, dUdy
+ // and dVdy.
+ TIntermSymbol *ma = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *l = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *uc = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *vc = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *dUdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *dVdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *dUdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *dVdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+
+ body->appendStatement(CreateTempDeclarationNode(&ma->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&l->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&uc->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&vc->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&dUdx->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&dVdx->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&dUdy->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&dVdy->variable()));
+
+ // ma = max(|x|, max(|y|, |z|))
+ TIntermSequence argsMaxYZ = {absY->deepCopy(), absZ->deepCopy()};
+ TIntermTyped *maxYZ = CreateBuiltInFunctionCallNode("max", &argsMaxYZ, *mSymbolTable, 100);
+ TIntermSequence argsMaxValue = {absX->deepCopy(), maxYZ};
+ TIntermTyped *maValue =
+ CreateBuiltInFunctionCallNode("max", &argsMaxValue, *mSymbolTable, 100);
+ body->appendStatement(new TIntermBinary(EOpAssign, ma, maValue));
+
+ // ma == |x| and ma == |y| expressions
+ TIntermTyped *isXMajor = new TIntermBinary(EOpEqual, ma->deepCopy(), absX->deepCopy());
+ TIntermTyped *isYMajor = new TIntermBinary(EOpEqual, ma->deepCopy(), absY->deepCopy());
+
+ // Determine the cube face:
+
+ // The case where x is major:
+ // layer = float(x < 0)
+ TIntermSequence argsNegX = {isNegX};
+ TIntermTyped *xl = TIntermAggregate::CreateConstructor(*floatType, &argsNegX);
+
+ TIntermBlock *calculateXL = new TIntermBlock;
+ calculateXL->appendStatement(new TIntermBinary(EOpAssign, l->deepCopy(), xl));
+
+ // The case where y is major:
+ // layer = 2 + float(y < 0)
+ TIntermSequence argsNegY = {isNegY};
+ TIntermTyped *yl =
+ new TIntermBinary(EOpAdd, CreateFloatNode(2.0f, EbpMedium),
+ TIntermAggregate::CreateConstructor(*floatType, &argsNegY));
+
+ TIntermBlock *calculateYL = new TIntermBlock;
+ calculateYL->appendStatement(new TIntermBinary(EOpAssign, l->deepCopy(), yl));
+
+ // The case where z is major:
+ // layer = 4 + float(z < 0)
+ TIntermSequence argsNegZ = {isNegZ};
+ TIntermTyped *zl =
+ new TIntermBinary(EOpAdd, CreateFloatNode(4.0f, EbpMedium),
+ TIntermAggregate::CreateConstructor(*floatType, &argsNegZ));
+
+ TIntermBlock *calculateZL = new TIntermBlock;
+ calculateZL->appendStatement(new TIntermBinary(EOpAssign, l->deepCopy(), zl));
+
+ // Create the if-else paths:
+ TIntermIfElse *calculateYZL = new TIntermIfElse(isYMajor, calculateYL, calculateZL);
+ TIntermBlock *calculateYZLBlock = new TIntermBlock;
+ calculateYZLBlock->appendStatement(calculateYZL);
+ TIntermIfElse *calculateXYZL = new TIntermIfElse(isXMajor, calculateXL, calculateYZLBlock);
+ body->appendStatement(calculateXYZL);
+
+ // layer < 1.5 (covering faces 0 and 1, corresponding to major axis being X) and layer < 3.5
+ // (covering faces 2 and 3, corresponding to major axis being Y). Used to determine which
+ // of the three transformations to apply. Previously, ma == |X| and ma == |Y| was used,
+ // which is no longer correct for helper invocations. The value of ma is updated in each
+ // case for these invocations.
+ isXMajor = new TIntermBinary(EOpLessThan, l->deepCopy(), CreateFloatNode(1.5f, EbpMedium));
+ isYMajor = new TIntermBinary(EOpLessThan, l->deepCopy(), CreateFloatNode(3.5f, EbpMedium));
+
+ TIntermSwizzle *dPdxX = new TIntermSwizzle(dPdx->deepCopy(), {0});
+ TIntermSwizzle *dPdxY = new TIntermSwizzle(dPdx->deepCopy(), {1});
+ TIntermSwizzle *dPdxZ = new TIntermSwizzle(dPdx->deepCopy(), {2});
+
+ TIntermSwizzle *dPdyX = new TIntermSwizzle(dPdy->deepCopy(), {0});
+ TIntermSwizzle *dPdyY = new TIntermSwizzle(dPdy->deepCopy(), {1});
+ TIntermSwizzle *dPdyZ = new TIntermSwizzle(dPdy->deepCopy(), {2});
+
+ TIntermBlock *calculateXUcVc = new TIntermBlock;
+ calculateXUcVc->appendStatement(
+ new TIntermBinary(EOpAssign, ma->deepCopy(), absX->deepCopy()));
+ TransformXMajor(*mSymbolTable, calculateXUcVc, x, y, z, uc, vc);
+
+ TIntermBlock *calculateYUcVc = new TIntermBlock;
+ calculateYUcVc->appendStatement(
+ new TIntermBinary(EOpAssign, ma->deepCopy(), absY->deepCopy()));
+ TransformYMajor(*mSymbolTable, calculateYUcVc, x, y, z, uc, vc);
+
+ TIntermBlock *calculateZUcVc = new TIntermBlock;
+ calculateZUcVc->appendStatement(
+ new TIntermBinary(EOpAssign, ma->deepCopy(), absZ->deepCopy()));
+ TransformZMajor(*mSymbolTable, calculateZUcVc, x, y, z, uc, vc);
+
+ // Compute derivatives.
+ if (implicit)
+ {
+ TransformImplicitDerivativeXMajor(calculateXUcVc, dPDXdx, dUdx, dVdx);
+ TransformImplicitDerivativeXMajor(calculateXUcVc, dPDXdy, dUdy, dVdy);
+ TransformImplicitDerivativeYMajor(calculateYUcVc, dPDYdx, dUdx, dVdx);
+ TransformImplicitDerivativeYMajor(calculateYUcVc, dPDYdy, dUdy, dVdy);
+ TransformImplicitDerivativeZMajor(calculateZUcVc, dPDZdx, dUdx, dVdx);
+ TransformImplicitDerivativeZMajor(calculateZUcVc, dPDZdy, dUdy, dVdy);
+ }
+ else
+ {
+ TransformDerivativeXMajor(calculateXUcVc, mSymbolTable, x, y, z, dPdxX, dPdxY, dPdxZ,
+ dUdx, dVdx, Swizzle1(pRecipVar->deepCopy(), 0));
+ TransformDerivativeXMajor(calculateXUcVc, mSymbolTable, x, y, z, dPdyX, dPdyY, dPdyZ,
+ dUdy, dVdy, Swizzle1(pRecipVar->deepCopy(), 0));
+ TransformDerivativeYMajor(calculateYUcVc, mSymbolTable, x, y, z, dPdxX, dPdxY, dPdxZ,
+ dUdx, dVdx, Swizzle1(pRecipVar->deepCopy(), 1));
+ TransformDerivativeYMajor(calculateYUcVc, mSymbolTable, x, y, z, dPdyX, dPdyY, dPdyZ,
+ dUdy, dVdy, Swizzle1(pRecipVar->deepCopy(), 1));
+ TransformDerivativeZMajor(calculateZUcVc, mSymbolTable, x, y, z, dPdxX, dPdxY, dPdxZ,
+ dUdx, dVdx, Swizzle1(pRecipVar->deepCopy(), 2));
+ TransformDerivativeZMajor(calculateZUcVc, mSymbolTable, x, y, z, dPdyX, dPdyY, dPdyZ,
+ dUdy, dVdy, Swizzle1(pRecipVar->deepCopy(), 2));
+ }
+
+ // Create the if-else paths:
+ TIntermIfElse *calculateYZUcVc =
+ new TIntermIfElse(isYMajor, calculateYUcVc, calculateZUcVc);
+ TIntermBlock *calculateYZUcVcBlock = new TIntermBlock;
+ calculateYZUcVcBlock->appendStatement(calculateYZUcVc);
+ TIntermIfElse *calculateXYZUcVc =
+ new TIntermIfElse(isXMajor, calculateXUcVc, calculateYZUcVcBlock);
+ body->appendStatement(calculateXYZUcVc);
+
+ // u = (1 + uc/|ma|) / 2
+ // v = (1 + vc/|ma|) / 2
+ TIntermTyped *maTimesTwoRecip = new TIntermBinary(
+ EOpAssign, ma->deepCopy(),
+ new TIntermBinary(EOpDiv, CreateFloatNode(0.5f, EbpMedium), ma->deepCopy()));
+ body->appendStatement(maTimesTwoRecip);
+
+ TIntermTyped *ucDivMa = new TIntermBinary(EOpMul, uc, ma->deepCopy());
+ TIntermTyped *vcDivMa = new TIntermBinary(EOpMul, vc, ma->deepCopy());
+ TIntermTyped *uNormalized =
+ new TIntermBinary(EOpAdd, CreateFloatNode(0.5f, EbpMedium), ucDivMa);
+ TIntermTyped *vNormalized =
+ new TIntermBinary(EOpAdd, CreateFloatNode(0.5f, EbpMedium), vcDivMa);
+
+ body->appendStatement(new TIntermBinary(EOpAssign, uc->deepCopy(), uNormalized));
+ body->appendStatement(new TIntermBinary(EOpAssign, vc->deepCopy(), vNormalized));
+
+ TIntermSequence argsDUVdx = {dUdx, dVdx};
+ TIntermTyped *dUVdxValue = TIntermAggregate::CreateConstructor(*vec2Type, &argsDUVdx);
+
+ TIntermSequence argsDUVdy = {dUdy, dVdy};
+ TIntermTyped *dUVdyValue = TIntermAggregate::CreateConstructor(*vec2Type, &argsDUVdy);
+
+ body->appendStatement(new TIntermBinary(EOpAssign, dUVdx, dUVdxValue));
+ body->appendStatement(new TIntermBinary(EOpAssign, dUVdy, dUVdyValue));
+
+ // return vec3(u, v, l)
+ TIntermSequence argsUVL = {uc->deepCopy(), vc->deepCopy(), l};
+ TIntermBranch *returnStatement =
+ new TIntermBranch(EOpReturn, TIntermAggregate::CreateConstructor(*vec3Type, &argsUVL));
+ body->appendStatement(returnStatement);
+
+ TFunction *function;
+ function = new TFunction(mSymbolTable, name, SymbolType::AngleInternal, vec3Type, true);
+ function->addParameter(pVar);
+ function->addParameter(dPdxVar);
+ function->addParameter(dPdyVar);
+ function->addParameter(dUVdxVar);
+ function->addParameter(dUVdyVar);
+
+ *functionOut = function;
+
+ *declOut = CreateInternalFunctionDefinitionNode(*function, body);
+ }
+
+ TIntermTyped *createCoordTransformationCall(TIntermTyped *P,
+ TIntermTyped *dPdx,
+ TIntermTyped *dPdy,
+ TIntermTyped *dUVdx,
+ TIntermTyped *dUVdy)
+ {
+ TIntermSequence args = {P, dPdx, dPdy, dUVdx, dUVdy};
+ return TIntermAggregate::CreateFunctionCall(*mCubeXYZToArrayUVL, &args);
+ }
+
+ TIntermTyped *createImplicitCoordTransformationCall(TIntermTyped *P,
+ TIntermTyped *dUVdx,
+ TIntermTyped *dUVdy)
+ {
+ const TType *vec3Type = StaticType::GetBasic<EbtFloat, EbpHigh, 3>();
+ TIntermTyped *dPdx = CreateZeroNode(*vec3Type);
+ TIntermTyped *dPdy = CreateZeroNode(*vec3Type);
+ TIntermSequence args = {P, dPdx, dPdy, dUVdx, dUVdy};
+ return TIntermAggregate::CreateFunctionCall(*mCubeXYZToArrayUVLImplicit, &args);
+ }
+
+ TIntermTyped *getMappedSamplerExpression(TIntermNode *samplerCubeExpression)
+ {
+ // The argument passed to a function can either be the sampler, if not array, or a subscript
+ // into the sampler array.
+ TIntermSymbol *asSymbol = samplerCubeExpression->getAsSymbolNode();
+ TIntermBinary *asBinary = samplerCubeExpression->getAsBinaryNode();
+
+ if (asBinary)
+ {
+ // Only constant indexing is supported in ES2.0.
+ ASSERT(asBinary->getOp() == EOpIndexDirect);
+ asSymbol = asBinary->getLeft()->getAsSymbolNode();
+ }
+
+ // Arrays of arrays are not available in ES2.0.
+ ASSERT(asSymbol != nullptr);
+ const TVariable *samplerCubeVar = &asSymbol->variable();
+
+ ASSERT(mSamplerMap.find(samplerCubeVar) != mSamplerMap.end());
+ const TVariable *mappedSamplerVar = mSamplerMap.at(samplerCubeVar);
+
+ TIntermTyped *mappedExpression = new TIntermSymbol(mappedSamplerVar);
+ if (asBinary)
+ {
+ mappedExpression =
+ new TIntermBinary(asBinary->getOp(), mappedExpression, asBinary->getRight());
+ }
+
+ return mappedExpression;
+ }
+
+ bool convertBuiltinFunction(TIntermAggregate *node)
+ {
+ const TFunction *function = node->getFunction();
+ if (!function->name().beginsWith("textureCube"))
+ {
+ return false;
+ }
+
+ // All textureCube* functions are in the form:
+ //
+ // textureCube??(samplerCube, vec3, ??)
+ //
+ // They should be converted to:
+ //
+ // texture??(sampler2DArray, convertCoords(vec3), ??)
+ //
+ // We assume the target platform supports texture() functions (currently only used in
+ // Vulkan).
+ //
+ // The intrinsics map as follows:
+ //
+ // textureCube -> textureGrad
+ // textureCubeLod -> textureLod
+ // textureCubeLodEXT -> textureLod
+ // textureCubeGrad -> textureGrad
+ // textureCubeGradEXT -> textureGrad
+ //
+ // Note that dPdx and dPdy in textureCubeGrad* are vec3, while the textureGrad equivalent
+ // for sampler2DArray is vec2. The EXT_shader_texture_lod that introduces thid function
+ // says:
+ //
+ // > For the "Grad" functions, dPdx is the explicit derivative of P with respect
+ // > to window x, and similarly dPdy with respect to window y. ... For a cube map texture,
+ // > dPdx and dPdy are vec3.
+ // >
+ // > Let
+ // >
+ // > dSdx = dPdx.s;
+ // > dSdy = dPdy.s;
+ // > dTdx = dPdx.t;
+ // > dTdy = dPdy.t;
+ // >
+ // > and
+ // >
+ // > / 0.0; for two-dimensional texture
+ // > dRdx = (
+ // > \ dPdx.p; for cube map texture
+ // >
+ // > / 0.0; for two-dimensional texture
+ // > dRdy = (
+ // > \ dPdy.p; for cube map texture
+ // >
+ // > (See equation 3.12a in The OpenGL ES 2.0 Specification.)
+ //
+ // It's unclear to me what dRdx and dRdy are. EXT_gpu_shader4 that promotes this function
+ // has the following additional information:
+ //
+ // > For the "Cube" versions, the partial
+ // > derivatives ddx and ddy are assumed to be in the coordinate system used
+ // > before texture coordinates are projected onto the appropriate cube
+ // > face. The partial derivatives of the post-projection texture coordinates,
+ // > which are used for level-of-detail and anisotropic filtering
+ // > calculations, are derived from coord, ddx and ddy in an
+ // > implementation-dependent manner.
+ //
+ // The calculation of dPdx and dPdy is declared as implementation-dependent, so we have
+ // freedom to calculate it as fit, even if not precisely the same as hardware might.
+
+ const char *substituteFunctionName = "textureGrad";
+ bool isGrad = false;
+ bool isTranslatedGrad = true;
+ bool hasBias = false;
+ if (function->name().beginsWith("textureCubeLod"))
+ {
+ substituteFunctionName = "textureLod";
+ isTranslatedGrad = false;
+ }
+ else if (function->name().beginsWith("textureCubeGrad"))
+ {
+ isGrad = true;
+ }
+ else if (!mIsFragmentShader)
+ {
+ substituteFunctionName = "texture";
+ isTranslatedGrad = false;
+ }
+
+ TIntermSequence *arguments = node->getSequence();
+ ASSERT(arguments->size() >= 2);
+
+ const TType *vec2Type = StaticType::GetBasic<EbtFloat, EbpHigh, 2>();
+ const TType *vec3Type = StaticType::GetBasic<EbtFloat, EbpHigh, 3>();
+ TIntermSymbol *uvl = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ TIntermSymbol *dUVdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec2Type));
+ TIntermSymbol *dUVdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec2Type));
+
+ TIntermTyped *dPdx = nullptr;
+ TIntermTyped *dPdy = nullptr;
+ if (isGrad)
+ {
+ ASSERT(arguments->size() == 4);
+ dPdx = (*arguments)[2]->getAsTyped()->deepCopy();
+ dPdy = (*arguments)[3]->getAsTyped()->deepCopy();
+ }
+ else if (isTranslatedGrad && mIsFragmentShader && arguments->size() == 3)
+ {
+ hasBias = true;
+ }
+ else
+ {
+ dPdx = CreateZeroNode(*vec3Type);
+ dPdy = CreateZeroNode(*vec3Type);
+ }
+
+ if (isTranslatedGrad && !mIsFragmentShader)
+ {
+ substituteFunctionName = "texture";
+ isTranslatedGrad = false;
+ }
+
+ // The function call to transform the coordinates, dPdx and dPdy. If not textureCubeGrad,
+ // the driver compiler will optimize out the unnecessary calculations.
+ TIntermSequence coordTransform;
+ coordTransform.push_back(CreateTempDeclarationNode(&dUVdx->variable()));
+ coordTransform.push_back(CreateTempDeclarationNode(&dUVdy->variable()));
+ TIntermTyped *coordTransformCall;
+ if (isGrad || !isTranslatedGrad)
+ {
+ coordTransformCall = createCoordTransformationCall(
+ (*arguments)[1]->getAsTyped()->deepCopy(), dPdx, dPdy, dUVdx, dUVdy);
+ }
+ else
+ {
+ coordTransformCall = createImplicitCoordTransformationCall(
+ (*arguments)[1]->getAsTyped()->deepCopy(), dUVdx, dUVdy);
+ }
+ coordTransform.push_back(
+ CreateTempInitDeclarationNode(&uvl->variable(), coordTransformCall));
+
+ TIntermTyped *dUVdxArg = dUVdx;
+ TIntermTyped *dUVdyArg = dUVdy;
+ if (hasBias)
+ {
+ const TType *floatType = StaticType::GetBasic<EbtFloat, EbpHigh>();
+ TIntermTyped *bias = (*arguments)[2]->getAsTyped()->deepCopy();
+ TIntermSequence exp2Args = {bias};
+ TIntermTyped *exp2Call =
+ CreateBuiltInFunctionCallNode("exp2", &exp2Args, *mSymbolTable, 100);
+ TIntermSymbol *biasFac = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ coordTransform.push_back(CreateTempInitDeclarationNode(&biasFac->variable(), exp2Call));
+ dUVdxArg =
+ new TIntermBinary(EOpVectorTimesScalar, biasFac->deepCopy(), dUVdx->deepCopy());
+ dUVdyArg =
+ new TIntermBinary(EOpVectorTimesScalar, biasFac->deepCopy(), dUVdy->deepCopy());
+ }
+
+ insertStatementsInParentBlock(coordTransform);
+
+ TIntermSequence substituteArguments;
+ // Replace the first argument (samplerCube) with the sampler2DArray.
+ substituteArguments.push_back(getMappedSamplerExpression((*arguments)[0]));
+ // Replace the second argument with the coordination transformation.
+ substituteArguments.push_back(uvl->deepCopy());
+ if (isTranslatedGrad)
+ {
+ substituteArguments.push_back(dUVdxArg->deepCopy());
+ substituteArguments.push_back(dUVdyArg->deepCopy());
+ }
+ else
+ {
+ // Pass the rest of the parameters as is.
+ for (size_t argIndex = 2; argIndex < arguments->size(); ++argIndex)
+ {
+ substituteArguments.push_back((*arguments)[argIndex]->getAsTyped()->deepCopy());
+ }
+ }
+
+ TIntermTyped *substituteCall = CreateBuiltInFunctionCallNode(
+ substituteFunctionName, &substituteArguments, *mSymbolTable, 300);
+
+ queueReplacement(substituteCall, OriginalNode::IS_DROPPED);
+
+ return true;
+ }
+
+ // A map from the samplerCube variable to the sampler2DArray one.
+ angle::HashMap<const TVariable *, const TVariable *> mSamplerMap;
+
+ // A helper function to convert xyz coordinates passed to a cube map sampling function into the
+ // array layer (cube map face) and uv coordinates.
+ TFunction *mCubeXYZToArrayUVL;
+ // A specialized version of the same function which uses implicit derivatives.
+ TFunction *mCubeXYZToArrayUVLImplicit;
+
+ bool mIsFragmentShader;
+
+ // Stored to be put before the first function after the pass.
+ TIntermFunctionDefinition *mCoordTranslationFunctionDecl;
+ TIntermFunctionDefinition *mCoordTranslationFunctionImplicitDecl;
+};
+} // anonymous namespace
+
+bool RewriteCubeMapSamplersAs2DArray(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ bool isFragmentShader)
+{
+ RewriteCubeMapSamplersAs2DArrayTraverser traverser(symbolTable, isFragmentShader);
+ root->traverse(&traverser);
+
+ TIntermFunctionDefinition *coordTranslationFunctionDecl =
+ traverser.getCoordTranslationFunctionDecl();
+ TIntermFunctionDefinition *coordTranslationFunctionDeclImplicit =
+ traverser.getCoordTranslationFunctionDeclImplicit();
+ size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(root);
+ if (coordTranslationFunctionDecl)
+ {
+ root->insertChildNodes(firstFunctionIndex, TIntermSequence({coordTranslationFunctionDecl}));
+ }
+ if (coordTranslationFunctionDeclImplicit)
+ {
+ root->insertChildNodes(firstFunctionIndex,
+ TIntermSequence({coordTranslationFunctionDeclImplicit}));
+ }
+
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.h
new file mode 100644
index 0000000000..515c1de103
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteCubeMapSamplersAs2DArray: Change samplerCube samplers to sampler2DArray, and the
+// textureCube* function calls to calls to helper functions that select the cube map face and sample
+// from the face as a 2D texture. This emulates seamful cube map sampling in ES2 (or desktop GL 2)
+// and therefore only looks at samplerCube (i.e. not integer variants or cube arrays) and sampling
+// functions that are defined in ES GLSL 1.0 (i.e. not the cube overload of texture()).
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITECUBEMAPSAMPLERSAS2DARRAY_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITECUBEMAPSAMPLERSAS2DARRAY_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteCubeMapSamplersAs2DArray(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ bool isFragmentShader);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITECUBEMAPSAMPLERSAS2DARRAY_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.cpp
new file mode 100644
index 0000000000..1a2aabf7dc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.cpp
@@ -0,0 +1,141 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Implementation of dFdy viewport transformation.
+// See header for more info.
+
+#include "compiler/translator/tree_ops/RewriteDfdy.h"
+
+#include "common/angleutils.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/TranslatorVulkan.h"
+#include "compiler/translator/tree_util/DriverUniform.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/SpecializationConstant.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class Traverser : public TIntermTraverser
+{
+ public:
+ Traverser(TSymbolTable *symbolTable, SpecConst *specConst, const DriverUniform *driverUniforms);
+
+ private:
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+ SpecConst *mSpecConst = nullptr;
+ const DriverUniform *mDriverUniforms = nullptr;
+};
+
+Traverser::Traverser(TSymbolTable *symbolTable,
+ SpecConst *specConst,
+ const DriverUniform *driverUniforms)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mSpecConst(specConst),
+ mDriverUniforms(driverUniforms)
+{}
+
+bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ // Decide if the node represents a call to dFdx() or dFdy()
+ if (node->getOp() != EOpDFdx && node->getOp() != EOpDFdy)
+ {
+ return true;
+ }
+
+ const bool isDFdx = node->getOp() == EOpDFdx;
+
+ // Two transformations are done on dFdx and dFdy:
+ //
+ // - If pre-rotation is applied, dFdx and dFdy may need to swap their axis based on the degree
+ // of rotation. dFdx becomes dFdy if rotation is 90 or 270 degrees. Similarly, dFdy becomes
+ // dFdx.
+ // - The result is potentially negated. This could be due to viewport y-flip or pre-rotation.
+ //
+ // Accordingly, there are two variables controlling the above transformations:
+ //
+ // - Rotation: A vec2 that is either (0, 1) or (1, 0). dFdx and dFdy are replaced with:
+ //
+ // dFdx * Rotation.x + dFdy * Rotation.y
+ //
+ // - Scale: A vec2 with -1 or 1 for either x or y components. The previous result is multiplied
+ // by this.
+ //
+ // Together, the above operations account for the combinations of 4 possible rotations and
+ // y-flip.
+
+ // Get the results of dFdx(operand) and dFdy(operand), and multiply them by the swizzles
+ TIntermTyped *operand = node->getChildNode(0)->getAsTyped();
+
+ TIntermTyped *dFdx = CreateBuiltInUnaryFunctionCallNode("dFdx", operand, *mSymbolTable, 300);
+ TIntermTyped *dFdy =
+ CreateBuiltInUnaryFunctionCallNode("dFdy", operand->deepCopy(), *mSymbolTable, 300);
+
+ // Get rotation multiplier
+ TIntermTyped *swapXY = mSpecConst->getSwapXY();
+ if (swapXY == nullptr)
+ {
+ swapXY = mDriverUniforms->getSwapXY();
+ }
+
+ TIntermTyped *swapXMultiplier = MakeSwapXMultiplier(swapXY);
+ TIntermTyped *swapYMultiplier = MakeSwapYMultiplier(swapXY->deepCopy());
+
+ // Get flip multiplier
+ TIntermTyped *flipXY = mDriverUniforms->getFlipXY(mSymbolTable, DriverUniformFlip::Fragment);
+
+ // Multiply the flip and rotation multipliers
+ TIntermTyped *xMultiplier =
+ new TIntermBinary(EOpMul, isDFdx ? swapXMultiplier : swapYMultiplier,
+ (new TIntermSwizzle(flipXY->deepCopy(), {0}))->fold(nullptr));
+ TIntermTyped *yMultiplier =
+ new TIntermBinary(EOpMul, isDFdx ? swapYMultiplier : swapXMultiplier,
+ (new TIntermSwizzle(flipXY->deepCopy(), {1}))->fold(nullptr));
+
+ const TOperator mulOp = dFdx->getType().isVector() ? EOpVectorTimesScalar : EOpMul;
+ TIntermTyped *rotatedFlippedDfdx = new TIntermBinary(mulOp, dFdx, xMultiplier);
+ TIntermTyped *rotatedFlippedDfdy = new TIntermBinary(mulOp, dFdy, yMultiplier);
+
+ // Sum them together into the result
+ TIntermBinary *rotatedFlippedResult =
+ new TIntermBinary(EOpAdd, rotatedFlippedDfdx, rotatedFlippedDfdy);
+
+ // Replace the old dFdx() or dFdy() node with the new node that contains the corrected value
+ //
+ // Note the following bugs (anglebug.com/7346):
+ //
+ // - Side effects of operand are duplicated with the above
+ // - If the direct child of this node is itself dFdx/y, its queueReplacement will not be
+ // effective as the parent is also replaced.
+ queueReplacement(rotatedFlippedResult, OriginalNode::IS_DROPPED);
+
+ return true;
+}
+} // anonymous namespace
+
+bool RewriteDfdy(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ SpecConst *specConst,
+ const DriverUniform *driverUniforms)
+{
+ // dFdx/dFdy is only valid in GLSL 3.0 and later.
+ if (shaderVersion < 300)
+ {
+ return true;
+ }
+
+ Traverser traverser(symbolTable, specConst, driverUniforms);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.h
new file mode 100644
index 0000000000..d1a6399696
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteDfdy: Transform dFdx and dFdy according to pre-rotation and viewport y-flip.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITEDFDY_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITEDFDY_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+class SpecConst;
+class DriverUniform;
+
+[[nodiscard]] bool RewriteDfdy(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ SpecConst *specConst,
+ const DriverUniform *driverUniforms);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITEDFDY_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.cpp
new file mode 100644
index 0000000000..1c86cafe03
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.cpp
@@ -0,0 +1,861 @@
+//
+// Copyright 2022 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_ops/RewritePixelLocalStorage.h"
+
+#include "common/angleutils.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+constexpr static TBasicType DataTypeOfPLSType(TBasicType plsType)
+{
+ switch (plsType)
+ {
+ case EbtPixelLocalANGLE:
+ return EbtFloat;
+ case EbtIPixelLocalANGLE:
+ return EbtInt;
+ case EbtUPixelLocalANGLE:
+ return EbtUInt;
+ default:
+ UNREACHABLE();
+ return EbtVoid;
+ }
+}
+
+constexpr static TBasicType DataTypeOfImageType(TBasicType imageType)
+{
+ switch (imageType)
+ {
+ case EbtImage2D:
+ return EbtFloat;
+ case EbtIImage2D:
+ return EbtInt;
+ case EbtUImage2D:
+ return EbtUInt;
+ default:
+ UNREACHABLE();
+ return EbtVoid;
+ }
+}
+
+// Maps PLS symbols to a backing store.
+template <typename T>
+class PLSBackingStoreMap
+{
+ public:
+ // Sets the given variable as the backing storage for the plsSymbol's binding point. An entry
+ // must not already exist in the map for this binding point.
+ void insertNew(TIntermSymbol *plsSymbol, const T &backingStore)
+ {
+ ASSERT(plsSymbol);
+ ASSERT(IsPixelLocal(plsSymbol->getBasicType()));
+ int binding = plsSymbol->getType().getLayoutQualifier().binding;
+ ASSERT(binding >= 0);
+ auto result = mMap.insert({binding, backingStore});
+ ASSERT(result.second); // Ensure an image didn't already exist for this symbol.
+ }
+
+ // Looks up the backing store for the given plsSymbol's binding point. An entry must already
+ // exist in the map for this binding point.
+ const T &find(TIntermSymbol *plsSymbol)
+ {
+ ASSERT(plsSymbol);
+ ASSERT(IsPixelLocal(plsSymbol->getBasicType()));
+ int binding = plsSymbol->getType().getLayoutQualifier().binding;
+ ASSERT(binding >= 0);
+ auto iter = mMap.find(binding);
+ ASSERT(iter != mMap.end()); // Ensure PLSImages already exist for this symbol.
+ return iter->second;
+ }
+
+ const std::map<int, T> &bindingOrderedMap() const { return mMap; }
+
+ private:
+ // Use std::map so the backing stores are ordered by binding when we iterate.
+ std::map<int, T> mMap;
+};
+
+// Base class for rewriting high level PLS operations to AST operations specified by
+// ShPixelLocalStorageType.
+class RewritePLSTraverser : public TIntermTraverser
+{
+ public:
+ RewritePLSTraverser(TCompiler *compiler,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ int shaderVersion)
+ : TIntermTraverser(true, false, false, &symbolTable),
+ mCompiler(compiler),
+ mCompileOptions(&compileOptions),
+ mShaderVersion(shaderVersion)
+ {}
+
+ bool visitDeclaration(Visit, TIntermDeclaration *decl) override
+ {
+ TIntermTyped *declVariable = (decl->getSequence())->front()->getAsTyped();
+ ASSERT(declVariable);
+
+ if (!IsPixelLocal(declVariable->getBasicType()))
+ {
+ return true;
+ }
+
+ // PLS is not allowed in arrays.
+ ASSERT(!declVariable->isArray());
+
+ // This visitDeclaration doesn't get called for function arguments, and opaque types can
+ // otherwise only be uniforms.
+ ASSERT(declVariable->getQualifier() == EvqUniform);
+
+ TIntermSymbol *plsSymbol = declVariable->getAsSymbolNode();
+ ASSERT(plsSymbol);
+
+ visitPLSDeclaration(plsSymbol);
+
+ return false;
+ }
+
+ bool visitAggregate(Visit, TIntermAggregate *aggregate) override
+ {
+ if (!BuiltInGroup::IsPixelLocal(aggregate->getOp()))
+ {
+ return true;
+ }
+
+ const TIntermSequence &args = *aggregate->getSequence();
+ ASSERT(args.size() >= 1);
+ TIntermSymbol *plsSymbol = args[0]->getAsSymbolNode();
+
+ // Rewrite pixelLocalLoadANGLE -> imageLoad.
+ if (aggregate->getOp() == EOpPixelLocalLoadANGLE)
+ {
+ visitPLSLoad(plsSymbol);
+ return false; // No need to recurse since this node is being dropped.
+ }
+
+ // Rewrite pixelLocalStoreANGLE -> imageStore.
+ if (aggregate->getOp() == EOpPixelLocalStoreANGLE)
+ {
+ // Also hoist the 'value' expression into a temp. In the event of
+ // "pixelLocalStoreANGLE(..., pixelLocalLoadANGLE(...))", this ensures the load occurs
+ // _before_ any potential barriers required by the subclass.
+ //
+ // NOTE: It is generally unsafe to hoist function arguments due to short circuiting,
+ // e.g., "if (false && function(...))", but pixelLocalStoreANGLE returns type void, so
+ // it is safe in this particular case.
+ TType *valueType = new TType(DataTypeOfPLSType(plsSymbol->getBasicType()),
+ plsSymbol->getPrecision(), EvqTemporary, 4);
+ TVariable *valueVar = CreateTempVariable(mSymbolTable, valueType);
+ TIntermDeclaration *valueDecl =
+ CreateTempInitDeclarationNode(valueVar, args[1]->getAsTyped());
+ valueDecl->traverse(this); // Rewrite any potential pixelLocalLoadANGLEs in valueDecl.
+ insertStatementInParentBlock(valueDecl);
+
+ visitPLSStore(plsSymbol, valueVar);
+ return false; // No need to recurse since this node is being dropped.
+ }
+
+ return true;
+ }
+
+ // Called after rewrite. Injects one-time setup code that needs to run before any PLS accesses.
+ virtual void injectSetupCode(TCompiler *,
+ TSymbolTable &,
+ const ShCompileOptions &,
+ TIntermBlock *mainBody,
+ size_t plsBeginPosition)
+ {}
+
+ // Called after rewrite. Injects one-time finalization code that needs to run after all PLS.
+ virtual void injectFinalizeCode(TCompiler *,
+ TSymbolTable &,
+ const ShCompileOptions &,
+ TIntermBlock *mainBody,
+ size_t plsEndPosition)
+ {}
+
+ TVariable *globalPixelCoord() const { return mGlobalPixelCoord; }
+
+ protected:
+ virtual void visitPLSDeclaration(TIntermSymbol *plsSymbol) = 0;
+ virtual void visitPLSLoad(TIntermSymbol *plsSymbol) = 0;
+ virtual void visitPLSStore(TIntermSymbol *plsSymbol, TVariable *value) = 0;
+
+ void ensureGlobalPixelCoordDeclared()
+ {
+ // Insert a global to hold the pixel coordinate as soon as we see PLS declared. This will be
+ // initialized at the beginning of main().
+ if (!mGlobalPixelCoord)
+ {
+ TType *coordType = new TType(EbtInt, EbpHigh, EvqGlobal, 2);
+ mGlobalPixelCoord = CreateTempVariable(mSymbolTable, coordType);
+ insertStatementInParentBlock(CreateTempDeclarationNode(mGlobalPixelCoord));
+ }
+ }
+
+ const TCompiler *const mCompiler;
+ const ShCompileOptions *const mCompileOptions;
+ const int mShaderVersion;
+
+ // Stores the shader invocation's pixel coordinate as "ivec2(floor(gl_FragCoord.xy))".
+ TVariable *mGlobalPixelCoord = nullptr;
+};
+
+// Rewrites high level PLS operations to shader image operations.
+class RewritePLSToImagesTraverser : public RewritePLSTraverser
+{
+ public:
+ RewritePLSToImagesTraverser(TCompiler *compiler,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ int shaderVersion)
+ : RewritePLSTraverser(compiler, symbolTable, compileOptions, shaderVersion)
+ {}
+
+ private:
+ void visitPLSDeclaration(TIntermSymbol *plsSymbol) override
+ {
+ // Replace the PLS declaration with an image2D.
+ ensureGlobalPixelCoordDeclared();
+ TVariable *image2D = createPLSImageReplacement(plsSymbol);
+ mImages.insertNew(plsSymbol, image2D);
+ queueReplacement(new TIntermDeclaration({new TIntermSymbol(image2D)}),
+ OriginalNode::IS_DROPPED);
+ }
+
+ // Do all PLS formats need to be packed into r32f, r32i, or r32ui image2Ds?
+ bool needsR32Packing() const
+ {
+ return mCompileOptions->pls.type == ShPixelLocalStorageType::ImageStoreR32PackedFormats;
+ }
+
+ // Creates an image2D that replaces a pixel local storage handle.
+ TVariable *createPLSImageReplacement(const TIntermSymbol *plsSymbol)
+ {
+ ASSERT(plsSymbol);
+ ASSERT(IsPixelLocal(plsSymbol->getBasicType()));
+
+ TType *imageType = new TType(plsSymbol->getType());
+
+ TLayoutQualifier layoutQualifier = imageType->getLayoutQualifier();
+ switch (layoutQualifier.imageInternalFormat)
+ {
+ case TLayoutImageInternalFormat::EiifRGBA8:
+ if (needsR32Packing())
+ {
+ layoutQualifier.imageInternalFormat = EiifR32UI;
+ imageType->setPrecision(EbpHigh);
+ imageType->setBasicType(EbtUImage2D);
+ }
+ else
+ {
+ imageType->setBasicType(EbtImage2D);
+ }
+ break;
+ case TLayoutImageInternalFormat::EiifRGBA8I:
+ if (needsR32Packing())
+ {
+ layoutQualifier.imageInternalFormat = EiifR32I;
+ imageType->setPrecision(EbpHigh);
+ }
+ imageType->setBasicType(EbtIImage2D);
+ break;
+ case TLayoutImageInternalFormat::EiifRGBA8UI:
+ if (needsR32Packing())
+ {
+ layoutQualifier.imageInternalFormat = EiifR32UI;
+ imageType->setPrecision(EbpHigh);
+ }
+ imageType->setBasicType(EbtUImage2D);
+ break;
+ case TLayoutImageInternalFormat::EiifR32F:
+ imageType->setBasicType(EbtImage2D);
+ break;
+ case TLayoutImageInternalFormat::EiifR32UI:
+ imageType->setBasicType(EbtUImage2D);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ layoutQualifier.rasterOrdered = mCompileOptions->pls.fragmentSynchronizationType ==
+ ShFragmentSynchronizationType::RasterizerOrderViews_D3D;
+ imageType->setLayoutQualifier(layoutQualifier);
+
+ TMemoryQualifier memoryQualifier{};
+ memoryQualifier.coherent = true;
+ memoryQualifier.restrictQualifier = true;
+ memoryQualifier.volatileQualifier = false;
+ // TODO(anglebug.com/7279): Maybe we could walk the tree first and see which PLS is used
+ // how. If the PLS is never loaded, we could add a writeonly qualifier, for example.
+ memoryQualifier.readonly = false;
+ memoryQualifier.writeonly = false;
+ imageType->setMemoryQualifier(memoryQualifier);
+
+ const TVariable &plsVar = plsSymbol->variable();
+ return new TVariable(plsVar.uniqueId(), plsVar.name(), plsVar.symbolType(),
+ plsVar.extensions(), imageType);
+ }
+
+ void visitPLSLoad(TIntermSymbol *plsSymbol) override
+ {
+ // Replace the pixelLocalLoadANGLE with imageLoad.
+ TVariable *image2D = mImages.find(plsSymbol);
+ ASSERT(mGlobalPixelCoord);
+ TIntermTyped *pls = CreateBuiltInFunctionCallNode(
+ "imageLoad", {new TIntermSymbol(image2D), new TIntermSymbol(mGlobalPixelCoord)},
+ *mSymbolTable, 310);
+ pls = unpackImageDataIfNecessary(pls, plsSymbol, image2D);
+ queueReplacement(pls, OriginalNode::IS_DROPPED);
+ }
+
+ // Unpacks the raw PLS data if the output shader language needs r32* packing.
+ TIntermTyped *unpackImageDataIfNecessary(TIntermTyped *data,
+ TIntermSymbol *plsSymbol,
+ TVariable *image2D)
+ {
+ TLayoutImageInternalFormat plsFormat =
+ plsSymbol->getType().getLayoutQualifier().imageInternalFormat;
+ TLayoutImageInternalFormat imageFormat =
+ image2D->getType().getLayoutQualifier().imageInternalFormat;
+ if (plsFormat == imageFormat)
+ {
+ return data; // This PLS storage isn't packed.
+ }
+ ASSERT(needsR32Packing());
+ switch (plsFormat)
+ {
+ case EiifRGBA8:
+ // Unpack and normalize r,g,b,a from a single 32-bit unsigned int:
+ //
+ // unpackUnorm4x8(data.r)
+ //
+ data = CreateBuiltInFunctionCallNode("unpackUnorm4x8", {CreateSwizzle(data, 0)},
+ *mSymbolTable, 310);
+ break;
+ case EiifRGBA8I:
+ case EiifRGBA8UI:
+ {
+ constexpr unsigned shifts[] = {24, 16, 8, 0};
+ // Unpack r,g,b,a form a single (signed or unsigned) 32-bit int. Shift left,
+ // then right, to preserve the sign for ints. (highp integers are exactly
+ // 32-bit, two's compliment.)
+ //
+ // data.rrrr << uvec4(24, 16, 8, 0) >> 24u
+ //
+ data = CreateSwizzle(data, 0, 0, 0, 0);
+ data = new TIntermBinary(EOpBitShiftLeft, data, CreateUVecNode(shifts, 4, EbpHigh));
+ data = new TIntermBinary(EOpBitShiftRight, data, CreateUIntNode(24));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ return data;
+ }
+
+ void visitPLSStore(TIntermSymbol *plsSymbol, TVariable *value) override
+ {
+ TVariable *image2D = mImages.find(plsSymbol);
+ TIntermTyped *packedData = clampAndPackPLSDataIfNecessary(value, plsSymbol, image2D);
+
+ // Surround the store with memoryBarrierImage calls in order to ensure dependent stores and
+ // loads in a single shader invocation are coherent. From the ES 3.1 spec:
+ //
+ // Using variables declared as "coherent" guarantees only that the results of stores will
+ // be immediately visible to shader invocations using similarly-declared variables;
+ // calling MemoryBarrier is required to ensure that the stores are visible to other
+ // operations.
+ //
+ insertStatementsInParentBlock(
+ {CreateBuiltInFunctionCallNode("memoryBarrierImage", {}, *mSymbolTable,
+ 310)}, // Before.
+ {CreateBuiltInFunctionCallNode("memoryBarrierImage", {}, *mSymbolTable,
+ 310)}); // After.
+
+ // Rewrite the pixelLocalStoreANGLE with imageStore.
+ ASSERT(mGlobalPixelCoord);
+ queueReplacement(
+ CreateBuiltInFunctionCallNode(
+ "imageStore",
+ {new TIntermSymbol(image2D), new TIntermSymbol(mGlobalPixelCoord), packedData},
+ *mSymbolTable, 310),
+ OriginalNode::IS_DROPPED);
+ }
+
+ // Packs the PLS to raw data if the output shader language needs r32* packing.
+ TIntermTyped *clampAndPackPLSDataIfNecessary(TVariable *plsVar,
+ TIntermSymbol *plsSymbol,
+ TVariable *image2D)
+ {
+ TLayoutImageInternalFormat plsFormat =
+ plsSymbol->getType().getLayoutQualifier().imageInternalFormat;
+ // anglebug.com/7524: Storing to integer formats with values larger than can be represented
+ // is specified differently on different APIs. Clamp integer formats here to make it uniform
+ // and more GL-like.
+ switch (plsFormat)
+ {
+ case EiifRGBA8I:
+ {
+ // Clamp r,g,b,a to their min/max 8-bit values:
+ //
+ // plsVar = clamp(plsVar, -128, 127) & 0xff
+ //
+ TIntermTyped *newPLSValue = CreateBuiltInFunctionCallNode(
+ "clamp",
+ {new TIntermSymbol(plsVar), CreateIndexNode(-128), CreateIndexNode(127)},
+ *mSymbolTable, mShaderVersion);
+ insertStatementInParentBlock(CreateTempAssignmentNode(plsVar, newPLSValue));
+ break;
+ }
+ case EiifRGBA8UI:
+ {
+ // Clamp r,g,b,a to their max 8-bit values:
+ //
+ // plsVar = min(plsVar, 255)
+ //
+ TIntermTyped *newPLSValue = CreateBuiltInFunctionCallNode(
+ "min", {new TIntermSymbol(plsVar), CreateUIntNode(255)}, *mSymbolTable,
+ mShaderVersion);
+ insertStatementInParentBlock(CreateTempAssignmentNode(plsVar, newPLSValue));
+ break;
+ }
+ default:
+ break;
+ }
+ TIntermTyped *result = new TIntermSymbol(plsVar);
+ TLayoutImageInternalFormat imageFormat =
+ image2D->getType().getLayoutQualifier().imageInternalFormat;
+ if (plsFormat == imageFormat)
+ {
+ return result; // This PLS storage isn't packed.
+ }
+ ASSERT(needsR32Packing());
+ switch (plsFormat)
+ {
+ case EiifRGBA8:
+ {
+ if (mCompileOptions->passHighpToPackUnormSnormBuiltins)
+ {
+ // anglebug.com/7527: unpackUnorm4x8 doesn't work on Pixel 4 when passed
+ // a mediump vec4. Use an intermediate highp vec4.
+ //
+ // It's safe to inject a variable here because it happens right before
+ // pixelLocalStoreANGLE, which returns type void. (See visitAggregate.)
+ TType *highpType = new TType(EbtFloat, EbpHigh, EvqTemporary, 4);
+ TVariable *workaroundHighpVar = CreateTempVariable(mSymbolTable, highpType);
+ insertStatementInParentBlock(
+ CreateTempInitDeclarationNode(workaroundHighpVar, result));
+ result = new TIntermSymbol(workaroundHighpVar);
+ }
+
+ // Denormalize and pack r,g,b,a into a single 32-bit unsigned int:
+ //
+ // packUnorm4x8(workaroundHighpVar)
+ //
+ result =
+ CreateBuiltInFunctionCallNode("packUnorm4x8", {result}, *mSymbolTable, 310);
+ break;
+ }
+ case EiifRGBA8I:
+ case EiifRGBA8UI:
+ {
+ if (plsFormat == EiifRGBA8I)
+ {
+ // Mask off extra sign bits beyond 8.
+ //
+ // plsVar &= 0xff
+ //
+ insertStatementInParentBlock(new TIntermBinary(
+ EOpBitwiseAndAssign, new TIntermSymbol(plsVar), CreateIndexNode(0xff)));
+ }
+ // Pack r,g,b,a into a single 32-bit (signed or unsigned) int:
+ //
+ // r | (g << 8) | (b << 16) | (a << 24)
+ //
+ auto shiftComponent = [=](int componentIdx) {
+ return new TIntermBinary(EOpBitShiftLeft,
+ CreateSwizzle(new TIntermSymbol(plsVar), componentIdx),
+ CreateUIntNode(componentIdx * 8));
+ };
+ result = CreateSwizzle(result, 0);
+ result = new TIntermBinary(EOpBitwiseOr, result, shiftComponent(1));
+ result = new TIntermBinary(EOpBitwiseOr, result, shiftComponent(2));
+ result = new TIntermBinary(EOpBitwiseOr, result, shiftComponent(3));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ // Convert the packed data to a {u,i}vec4 for imageStore.
+ TType imageStoreType(DataTypeOfImageType(image2D->getType().getBasicType()), 4);
+ return TIntermAggregate::CreateConstructor(imageStoreType, {result});
+ }
+
+ void injectSetupCode(TCompiler *compiler,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ TIntermBlock *mainBody,
+ size_t plsBeginPosition) override
+ {
+ // When PLS is implemented with images, early_fragment_tests ensure that depth/stencil
+ // can also block stores to PLS.
+ compiler->specifyEarlyFragmentTests();
+
+ // Delimit the beginning of a per-pixel critical section, if supported. This makes pixel
+ // local storage coherent.
+ //
+ // Either: GL_NV_fragment_shader_interlock
+ // GL_INTEL_fragment_shader_ordering
+ // GL_ARB_fragment_shader_interlock (may compile to
+ // SPV_EXT_fragment_shader_interlock)
+ switch (compileOptions.pls.fragmentSynchronizationType)
+ {
+ // ROVs don't need explicit synchronization calls.
+ case ShFragmentSynchronizationType::RasterizerOrderViews_D3D:
+ case ShFragmentSynchronizationType::NotSupported:
+ break;
+ case ShFragmentSynchronizationType::FragmentShaderInterlock_NV_GL:
+ mainBody->insertStatement(
+ plsBeginPosition,
+ CreateBuiltInFunctionCallNode("beginInvocationInterlockNV", {}, symbolTable,
+ kESSLInternalBackendBuiltIns));
+ break;
+ case ShFragmentSynchronizationType::FragmentShaderOrdering_INTEL_GL:
+ mainBody->insertStatement(
+ plsBeginPosition,
+ CreateBuiltInFunctionCallNode("beginFragmentShaderOrderingINTEL", {},
+ symbolTable, kESSLInternalBackendBuiltIns));
+ break;
+ case ShFragmentSynchronizationType::FragmentShaderInterlock_ARB_GL:
+ mainBody->insertStatement(
+ plsBeginPosition,
+ CreateBuiltInFunctionCallNode("beginInvocationInterlockARB", {}, symbolTable,
+ kESSLInternalBackendBuiltIns));
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ void injectFinalizeCode(TCompiler *,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ TIntermBlock *mainBody,
+ size_t plsEndPosition) override
+ {
+ // Delimit the end of the PLS critical section, if required.
+ //
+ // Either: GL_NV_fragment_shader_interlock
+ // GL_ARB_fragment_shader_interlock (may compile to
+ // SPV_EXT_fragment_shader_interlock)
+ switch (compileOptions.pls.fragmentSynchronizationType)
+ {
+ // ROVs don't need explicit synchronization calls.
+ case ShFragmentSynchronizationType::RasterizerOrderViews_D3D:
+ // GL_INTEL_fragment_shader_ordering doesn't have an "end()" call.
+ case ShFragmentSynchronizationType::FragmentShaderOrdering_INTEL_GL:
+ case ShFragmentSynchronizationType::NotSupported:
+ break;
+ case ShFragmentSynchronizationType::FragmentShaderInterlock_NV_GL:
+
+ mainBody->insertStatement(
+ plsEndPosition,
+ CreateBuiltInFunctionCallNode("endInvocationInterlockNV", {}, symbolTable,
+ kESSLInternalBackendBuiltIns));
+ break;
+ case ShFragmentSynchronizationType::FragmentShaderInterlock_ARB_GL:
+ mainBody->insertStatement(
+ plsEndPosition,
+ CreateBuiltInFunctionCallNode("endInvocationInterlockARB", {}, symbolTable,
+ kESSLInternalBackendBuiltIns));
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ PLSBackingStoreMap<TVariable *> mImages;
+};
+
+// Rewrites high level PLS operations to framebuffer fetch operations.
+class RewritePLSToFramebufferFetchTraverser : public RewritePLSTraverser
+{
+ public:
+ RewritePLSToFramebufferFetchTraverser(TCompiler *compiler,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ int shaderVersion)
+ : RewritePLSTraverser(compiler, symbolTable, compileOptions, shaderVersion)
+ {}
+
+ void visitPLSDeclaration(TIntermSymbol *plsSymbol) override
+ {
+ // Replace the PLS declaration with a framebuffer attachment.
+ PLSAttachment attachment(mCompiler, mSymbolTable, *mCompileOptions, plsSymbol->variable());
+ mPLSAttachments.insertNew(plsSymbol, attachment);
+ insertStatementInParentBlock(
+ new TIntermDeclaration({new TIntermSymbol(attachment.fragmentVar)}));
+ queueReplacement(CreateTempDeclarationNode(attachment.accessVar), OriginalNode::IS_DROPPED);
+ }
+
+ void visitPLSLoad(TIntermSymbol *plsSymbol) override
+ {
+ // Read our temporary accessVar.
+ const PLSAttachment &attachment = mPLSAttachments.find(plsSymbol);
+ queueReplacement(attachment.expandAccessVar(), OriginalNode::IS_DROPPED);
+ }
+
+ void visitPLSStore(TIntermSymbol *plsSymbol, TVariable *value) override
+ {
+ // Set our temporary accessVar.
+ const PLSAttachment &attachment = mPLSAttachments.find(plsSymbol);
+ queueReplacement(CreateTempAssignmentNode(attachment.accessVar, attachment.swizzle(value)),
+ OriginalNode::IS_DROPPED);
+ }
+
+ void injectSetupCode(TCompiler *compiler,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ TIntermBlock *mainBody,
+ size_t plsBeginPosition) override
+ {
+ // [OpenGL ES Version 3.0.6, 3.9.2.3 "Shader Output"]: Any colors, or color components,
+ // associated with a fragment that are not written by the fragment shader are undefined.
+ //
+ // [EXT_shader_framebuffer_fetch]: Prior to fragment shading, fragment outputs declared
+ // inout are populated with the value last written to the framebuffer at the same(x, y,
+ // sample) position.
+ //
+ // It's unclear from the EXT_shader_framebuffer_fetch spec whether inout fragment variables
+ // become undefined if not explicitly written, but either way, when this compiles to subpass
+ // loads in Vulkan, we definitely get undefined behavior if PLS variables are not written.
+ //
+ // To make sure every PLS variable gets written, we read them all before PLS operations,
+ // then write them all back out after all PLS is complete.
+ std::vector<TIntermNode *> plsPreloads;
+ plsPreloads.reserve(mPLSAttachments.bindingOrderedMap().size());
+ for (const auto &entry : mPLSAttachments.bindingOrderedMap())
+ {
+ const PLSAttachment &attachment = entry.second;
+ plsPreloads.push_back(
+ CreateTempAssignmentNode(attachment.accessVar, attachment.swizzleFragmentVar()));
+ }
+ mainBody->getSequence()->insert(mainBody->getSequence()->begin() + plsBeginPosition,
+ plsPreloads.begin(), plsPreloads.end());
+ }
+
+ void injectFinalizeCode(TCompiler *,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ TIntermBlock *mainBody,
+ size_t plsEndPosition) override
+ {
+ std::vector<TIntermNode *> plsWrites;
+ plsWrites.reserve(mPLSAttachments.bindingOrderedMap().size());
+ for (const auto &entry : mPLSAttachments.bindingOrderedMap())
+ {
+ const PLSAttachment &attachment = entry.second;
+ plsWrites.push_back(new TIntermBinary(EOpAssign, attachment.swizzleFragmentVar(),
+ new TIntermSymbol(attachment.accessVar)));
+ }
+ mainBody->getSequence()->insert(mainBody->getSequence()->begin() + plsEndPosition,
+ plsWrites.begin(), plsWrites.end());
+ }
+
+ private:
+ struct PLSAttachment
+ {
+ PLSAttachment(const TCompiler *compiler,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ const TVariable &plsVar)
+ {
+ const TType &plsType = plsVar.getType();
+
+ TType *accessVarType;
+ switch (plsType.getLayoutQualifier().imageInternalFormat)
+ {
+ default:
+ UNREACHABLE();
+ [[fallthrough]];
+ case EiifRGBA8:
+ accessVarType = new TType(EbtFloat, 4);
+ break;
+ case EiifRGBA8I:
+ accessVarType = new TType(EbtInt, 4);
+ break;
+ case EiifRGBA8UI:
+ accessVarType = new TType(EbtUInt, 4);
+ break;
+ case EiifR32F:
+ accessVarType = new TType(EbtFloat, 1);
+ break;
+ case EiifR32UI:
+ accessVarType = new TType(EbtUInt, 1);
+ break;
+ }
+ accessVarType->setPrecision(plsType.getPrecision());
+ accessVar = CreateTempVariable(symbolTable, accessVarType);
+
+ // Qualcomm seems to want fragment outputs to be 4-component vectors, and produces a
+ // compile error from "inout uint". Our Metal translator also saturates color outputs to
+ // 4 components. And since the spec also seems silent on how many components an output
+ // must have, we always use 4.
+ TType *fragmentVarType = new TType(accessVarType->getBasicType(), 4);
+ fragmentVarType->setPrecision(plsType.getPrecision());
+ fragmentVarType->setQualifier(EvqFragmentInOut);
+
+ // PLS attachments are bound in reverse order from the rear.
+ TLayoutQualifier layoutQualifier = TLayoutQualifier::Create();
+ layoutQualifier.location =
+ compiler->getResources().MaxCombinedDrawBuffersAndPixelLocalStoragePlanes -
+ plsType.getLayoutQualifier().binding - 1;
+ layoutQualifier.locationsSpecified = 1;
+ if (compileOptions.pls.fragmentSynchronizationType ==
+ ShFragmentSynchronizationType::NotSupported)
+ {
+ // We're using EXT_shader_framebuffer_fetch_non_coherent, which requires the
+ // "noncoherent" qualifier.
+ layoutQualifier.noncoherent = true;
+ }
+ fragmentVarType->setLayoutQualifier(layoutQualifier);
+
+ fragmentVar = new TVariable(plsVar.uniqueId(), plsVar.name(), plsVar.symbolType(),
+ plsVar.extensions(), fragmentVarType);
+ }
+
+ // Expands our accessVar to 4 components, regardless of the size of the pixel local storage
+ // internalformat.
+ TIntermTyped *expandAccessVar() const
+ {
+ TIntermTyped *expanded = new TIntermSymbol(accessVar);
+ if (accessVar->getType().getNominalSize() == 1)
+ {
+ switch (accessVar->getType().getBasicType())
+ {
+ case EbtFloat:
+ expanded = TIntermAggregate::CreateConstructor( // "vec4(r, 0, 0, 1)"
+ TType(EbtFloat, 4),
+ {expanded, CreateFloatNode(0, EbpHigh), CreateFloatNode(0, EbpHigh),
+ CreateFloatNode(1, EbpHigh)});
+ break;
+ case EbtUInt:
+ expanded = TIntermAggregate::CreateConstructor( // "uvec4(r, 0, 0, 1)"
+ TType(EbtUInt, 4),
+ {expanded, CreateUIntNode(0), CreateUIntNode(0), CreateUIntNode(1)});
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ return expanded;
+ }
+
+ // Swizzles a variable down to the same number of components as the PLS internalformat.
+ TIntermTyped *swizzle(TVariable *var) const
+ {
+ TIntermTyped *swizzled = new TIntermSymbol(var);
+ if (var->getType().getNominalSize() != accessVar->getType().getNominalSize())
+ {
+ ASSERT(var->getType().getNominalSize() > accessVar->getType().getNominalSize());
+ TVector swizzleOffsets{0, 1, 2, 3};
+ swizzleOffsets.resize(accessVar->getType().getNominalSize());
+ swizzled = new TIntermSwizzle(swizzled, swizzleOffsets);
+ }
+ return swizzled;
+ }
+
+ TIntermTyped *swizzleFragmentVar() const { return swizzle(fragmentVar); }
+
+ TVariable *fragmentVar;
+ TVariable *accessVar;
+ };
+
+ PLSBackingStoreMap<PLSAttachment> mPLSAttachments;
+};
+} // anonymous namespace
+
+bool RewritePixelLocalStorage(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ int shaderVersion)
+{
+ // If any functions take PLS arguments, monomorphize the functions by removing said parameters
+ // and making the PLS calls from main() instead, using the global uniform from the call site
+ // instead of the function argument. This is necessary because function arguments don't carry
+ // the necessary "binding" or "format" layout qualifiers.
+ if (!MonomorphizeUnsupportedFunctions(
+ compiler, root, &symbolTable, compileOptions,
+ UnsupportedFunctionArgsBitSet{UnsupportedFunctionArgs::PixelLocalStorage}))
+ {
+ return false;
+ }
+
+ TIntermBlock *mainBody = FindMainBody(root);
+
+ std::unique_ptr<RewritePLSTraverser> traverser;
+ switch (compileOptions.pls.type)
+ {
+ case ShPixelLocalStorageType::ImageStoreR32PackedFormats:
+ case ShPixelLocalStorageType::ImageStoreNativeFormats:
+ traverser = std::make_unique<RewritePLSToImagesTraverser>(
+ compiler, symbolTable, compileOptions, shaderVersion);
+ break;
+ case ShPixelLocalStorageType::FramebufferFetch:
+ traverser = std::make_unique<RewritePLSToFramebufferFetchTraverser>(
+ compiler, symbolTable, compileOptions, shaderVersion);
+ break;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+
+ // Rewrite PLS operations to image operations.
+ root->traverse(traverser.get());
+ if (!traverser->updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ // Inject the code that needs to run before and after all PLS operations.
+ // TODO(anglebug.com/7279): Inject these functions in a tight critical section, instead of
+ // just locking the entire main() function:
+ // - Monomorphize all PLS calls into main().
+ // - Insert begin/end calls around the first/last PLS calls (and outside of flow control).
+ traverser->injectSetupCode(compiler, symbolTable, compileOptions, mainBody, 0);
+ traverser->injectFinalizeCode(compiler, symbolTable, compileOptions, mainBody,
+ mainBody->getChildCount());
+
+ if (traverser->globalPixelCoord())
+ {
+ // Initialize the global pixel coord at the beginning of main():
+ //
+ // pixelCoord = ivec2(floor(gl_FragCoord.xy));
+ //
+ TIntermTyped *exp;
+ exp = ReferenceBuiltInVariable(ImmutableString("gl_FragCoord"), symbolTable, shaderVersion);
+ exp = CreateSwizzle(exp, 0, 1);
+ exp = CreateBuiltInFunctionCallNode("floor", {exp}, symbolTable, shaderVersion);
+ exp = TIntermAggregate::CreateConstructor(TType(EbtInt, 2), {exp});
+ exp = CreateTempAssignmentNode(traverser->globalPixelCoord(), exp);
+ mainBody->insertStatement(0, exp);
+ }
+
+ return compiler->validateAST(root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.h
new file mode 100644
index 0000000000..9bcfcbb62e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2022 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITE_PIXELLOCALSTORAGE_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITE_PIXELLOCALSTORAGE_H_
+
+#include <GLSLANG/ShaderLang.h>
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+// This mutating tree traversal rewrites high level ANGLE_shader_pixel_local_storage operations to
+// the type of shader operations specified by ShPixelLocalStorageType, found in ShCompileOptions.
+[[nodiscard]] bool RewritePixelLocalStorage(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ int shaderVersion);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITE_PIXELLOCALSTORAGE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.cpp
new file mode 100644
index 0000000000..219a6b31fc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.cpp
@@ -0,0 +1,673 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteStructSamplers: Extract samplers from structs.
+//
+
+#include "compiler/translator/tree_ops/RewriteStructSamplers.h"
+
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+
+// Used to map one structure type to another (one where the samplers are removed).
+struct StructureData
+{
+ // The structure this was replaced with. If nullptr, it means the structure is removed (because
+ // it had all samplers).
+ const TStructure *modified;
+ // Indexed by the field index of original structure, to get the field index of the modified
+ // structure. For example:
+ //
+ // struct Original
+ // {
+ // sampler2D s1;
+ // vec4 f1;
+ // sampler2D s2;
+ // sampler2D s3;
+ // vec4 f2;
+ // };
+ //
+ // struct Modified
+ // {
+ // vec4 f1;
+ // vec4 f2;
+ // };
+ //
+ // fieldMap:
+ // 0 -> Invalid
+ // 1 -> 0
+ // 2 -> Invalid
+ // 3 -> Invalid
+ // 4 -> 1
+ //
+ TVector<int> fieldMap;
+};
+
+using StructureMap = angle::HashMap<const TStructure *, StructureData>;
+using StructureUniformMap = angle::HashMap<const TVariable *, const TVariable *>;
+using ExtractedSamplerMap = angle::HashMap<std::string, const TVariable *>;
+
+TIntermTyped *RewriteModifiedStructFieldSelectionExpression(
+ TCompiler *compiler,
+ TIntermBinary *node,
+ const StructureMap &structureMap,
+ const StructureUniformMap &structureUniformMap,
+ const ExtractedSamplerMap &extractedSamplers);
+
+TIntermTyped *RewriteExpressionVisitBinaryHelper(TCompiler *compiler,
+ TIntermBinary *node,
+ const StructureMap &structureMap,
+ const StructureUniformMap &structureUniformMap,
+ const ExtractedSamplerMap &extractedSamplers)
+{
+ // Only interested in EOpIndexDirectStruct binary nodes.
+ if (node->getOp() != EOpIndexDirectStruct)
+ {
+ return nullptr;
+ }
+
+ const TStructure *structure = node->getLeft()->getType().getStruct();
+ ASSERT(structure);
+
+ // If the result of the index is not a sampler and the struct is not replaced, there's nothing
+ // to do.
+ if (!node->getType().isSampler() && structureMap.find(structure) == structureMap.end())
+ {
+ return nullptr;
+ }
+
+ // Otherwise, replace the whole expression such that:
+ //
+ // - if sampler, it's indexed with whatever indices the parent structs were indexed with,
+ // - otherwise, the chain of field selections is rewritten by modifying the base uniform so all
+ // the intermediate nodes would have the correct type (and therefore fields).
+ ASSERT(structureMap.find(structure) != structureMap.end());
+
+ return RewriteModifiedStructFieldSelectionExpression(compiler, node, structureMap,
+ structureUniformMap, extractedSamplers);
+}
+
+// Given an expression, this traverser calculates a new expression where sampler-in-structs are
+// replaced with their extracted ones, and field indices are adjusted for the rest of the fields.
+// In particular, this is run on the right node of EOpIndexIndirect binary nodes, so that the
+// expression in the index gets a chance to go through this transformation.
+class RewriteExpressionTraverser final : public TIntermTraverser
+{
+ public:
+ explicit RewriteExpressionTraverser(TCompiler *compiler,
+ const StructureMap &structureMap,
+ const StructureUniformMap &structureUniformMap,
+ const ExtractedSamplerMap &extractedSamplers)
+ : TIntermTraverser(true, false, false),
+ mCompiler(compiler),
+ mStructureMap(structureMap),
+ mStructureUniformMap(structureUniformMap),
+ mExtractedSamplers(extractedSamplers)
+ {}
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TIntermTyped *rewritten = RewriteExpressionVisitBinaryHelper(
+ mCompiler, node, mStructureMap, mStructureUniformMap, mExtractedSamplers);
+
+ if (rewritten == nullptr)
+ {
+ return true;
+ }
+
+ queueReplacement(rewritten, OriginalNode::IS_DROPPED);
+
+ // Don't iterate as the expression is rewritten.
+ return false;
+ }
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ // It's impossible to reach here with a symbol that needs replacement.
+ // MonomorphizeUnsupportedFunctions makes sure that whole structs containing
+ // samplers are not passed to functions, so any instance of the struct uniform is
+ // necessarily indexed right away. visitBinary should have already taken care of it.
+ ASSERT(mStructureUniformMap.find(&node->variable()) == mStructureUniformMap.end());
+ }
+
+ private:
+ TCompiler *mCompiler;
+
+ // See RewriteStructSamplersTraverser.
+ const StructureMap &mStructureMap;
+ const StructureUniformMap &mStructureUniformMap;
+ const ExtractedSamplerMap &mExtractedSamplers;
+};
+
+// Rewrite the index of an EOpIndexIndirect expression. The root can never need replacing, because
+// it cannot be a sampler itself or of a struct type.
+void RewriteIndexExpression(TCompiler *compiler,
+ TIntermTyped *expression,
+ const StructureMap &structureMap,
+ const StructureUniformMap &structureUniformMap,
+ const ExtractedSamplerMap &extractedSamplers)
+{
+ RewriteExpressionTraverser traverser(compiler, structureMap, structureUniformMap,
+ extractedSamplers);
+ expression->traverse(&traverser);
+ bool valid = traverser.updateTree(compiler, expression);
+ ASSERT(valid);
+}
+
+// Given an expression such as the following:
+//
+// EOpIndexDirectStruct (sampler)
+// / \
+// EOpIndex* field index
+// / \
+// EOpIndexDirectStruct index 2
+// / \
+// EOpIndex* field index
+// / \
+// EOpIndexDirectStruct index 1
+// / \
+// Uniform Struct field index
+//
+// produces:
+//
+// EOpIndex*
+// / \
+// EOpIndex* index 2
+// / \
+// sampler index 1
+//
+// Alternatively, if the expression is as such:
+//
+// EOpIndexDirectStruct
+// / \
+// (modified struct type) EOpIndex* field index
+// / \
+// EOpIndexDirectStruct index 2
+// / \
+// EOpIndex* field index
+// / \
+// EOpIndexDirectStruct index 1
+// / \
+// Uniform Struct field index
+//
+// produces:
+//
+// EOpIndexDirectStruct
+// / \
+// EOpIndex* mapped field index
+// / \
+// EOpIndexDirectStruct index 2
+// / \
+// EOpIndex* mapped field index
+// / \
+// EOpIndexDirectStruct index 1
+// / \
+// Uniform Struct mapped field index
+//
+TIntermTyped *RewriteModifiedStructFieldSelectionExpression(
+ TCompiler *compiler,
+ TIntermBinary *node,
+ const StructureMap &structureMap,
+ const StructureUniformMap &structureUniformMap,
+ const ExtractedSamplerMap &extractedSamplers)
+{
+ ASSERT(node->getOp() == EOpIndexDirectStruct);
+
+ const bool isSampler = node->getType().isSampler();
+
+ TIntermSymbol *baseUniform = nullptr;
+ std::string samplerName;
+
+ TVector<TIntermBinary *> indexNodeStack;
+
+ // Iterate once and build the name of the sampler.
+ TIntermBinary *iter = node;
+ while (baseUniform == nullptr)
+ {
+ indexNodeStack.push_back(iter);
+ baseUniform = iter->getLeft()->getAsSymbolNode();
+
+ if (isSampler)
+ {
+ if (iter->getOp() == EOpIndexDirectStruct)
+ {
+ // When indexed into a struct, get the field name instead and construct the sampler
+ // name.
+ samplerName.insert(0, iter->getIndexStructFieldName().data());
+ samplerName.insert(0, "_");
+ }
+
+ if (baseUniform)
+ {
+ // If left is a symbol, we have reached the end of the chain. Use the struct name
+ // to finish building the name of the sampler.
+ samplerName.insert(0, baseUniform->variable().name().data());
+ }
+ }
+
+ iter = iter->getLeft()->getAsBinaryNode();
+ }
+
+ TIntermTyped *rewritten = nullptr;
+
+ if (isSampler)
+ {
+ ASSERT(extractedSamplers.find(samplerName) != extractedSamplers.end());
+ rewritten = new TIntermSymbol(extractedSamplers.at(samplerName));
+ }
+ else
+ {
+ const TVariable *baseUniformVar = &baseUniform->variable();
+ ASSERT(structureUniformMap.find(baseUniformVar) != structureUniformMap.end());
+ rewritten = new TIntermSymbol(structureUniformMap.at(baseUniformVar));
+ }
+
+ // Iterate again and build the expression from bottom up.
+ for (auto it = indexNodeStack.rbegin(); it != indexNodeStack.rend(); ++it)
+ {
+ TIntermBinary *indexNode = *it;
+
+ switch (indexNode->getOp())
+ {
+ case EOpIndexDirectStruct:
+ if (!isSampler)
+ {
+ // Remap the field.
+ const TStructure *structure = indexNode->getLeft()->getType().getStruct();
+ ASSERT(structureMap.find(structure) != structureMap.end());
+
+ TIntermConstantUnion *asConstantUnion =
+ indexNode->getRight()->getAsConstantUnion();
+ ASSERT(asConstantUnion);
+
+ const int fieldIndex = asConstantUnion->getIConst(0);
+ ASSERT(fieldIndex <
+ static_cast<int>(structureMap.at(structure).fieldMap.size()));
+
+ const int mappedFieldIndex = structureMap.at(structure).fieldMap[fieldIndex];
+
+ rewritten = new TIntermBinary(EOpIndexDirectStruct, rewritten,
+ CreateIndexNode(mappedFieldIndex));
+ }
+ break;
+
+ case EOpIndexDirect:
+ rewritten = new TIntermBinary(EOpIndexDirect, rewritten, indexNode->getRight());
+ break;
+
+ case EOpIndexIndirect:
+ {
+ // Run RewriteExpressionTraverser on the right node. It may itself be an expression
+ // with a sampler inside that needs to be rewritten, or simply use a field of a
+ // struct that's remapped.
+ TIntermTyped *indexExpression = indexNode->getRight();
+ RewriteIndexExpression(compiler, indexExpression, structureMap, structureUniformMap,
+ extractedSamplers);
+ rewritten = new TIntermBinary(EOpIndexIndirect, rewritten, indexExpression);
+ break;
+ }
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+
+ return rewritten;
+}
+
+class RewriteStructSamplersTraverser final : public TIntermTraverser
+{
+ public:
+ explicit RewriteStructSamplersTraverser(TCompiler *compiler, TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mCompiler(compiler),
+ mRemovedUniformsCount(0)
+ {}
+
+ int removedUniformsCount() const { return mRemovedUniformsCount; }
+
+ // Each struct sampler declaration is stripped of its samplers. New uniforms are added for each
+ // stripped struct sampler.
+ bool visitDeclaration(Visit visit, TIntermDeclaration *decl) override
+ {
+ if (!mInGlobalScope)
+ {
+ return true;
+ }
+
+ const TIntermSequence &sequence = *(decl->getSequence());
+ TIntermTyped *declarator = sequence.front()->getAsTyped();
+ const TType &type = declarator->getType();
+
+ if (!type.isStructureContainingSamplers())
+ {
+ return false;
+ }
+
+ TIntermSequence newSequence;
+
+ if (type.isStructSpecifier())
+ {
+ // If this is just a struct definition (not a uniform variable declaration of a
+ // struct type), just remove the samplers. They are not instantiated yet.
+ const TStructure *structure = type.getStruct();
+ ASSERT(structure && mStructureMap.find(structure) == mStructureMap.end());
+
+ stripStructSpecifierSamplers(structure, &newSequence);
+ }
+ else
+ {
+ const TStructure *structure = type.getStruct();
+
+ // If the structure is defined at the same time, create the mapping to the stripped
+ // version first.
+ if (mStructureMap.find(structure) == mStructureMap.end())
+ {
+ stripStructSpecifierSamplers(structure, &newSequence);
+ }
+
+ // Then, extract the samplers from the struct and create global-scope variables instead.
+ TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
+ ASSERT(asSymbol);
+ const TVariable &variable = asSymbol->variable();
+ ASSERT(variable.symbolType() != SymbolType::Empty);
+
+ extractStructSamplerUniforms(variable, structure, &newSequence);
+ }
+
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), decl,
+ std::move(newSequence));
+
+ return false;
+ }
+
+ // Same implementation as in RewriteExpressionTraverser. That traverser cannot replace root.
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TIntermTyped *rewritten = RewriteExpressionVisitBinaryHelper(
+ mCompiler, node, mStructureMap, mStructureUniformMap, mExtractedSamplers);
+
+ if (rewritten == nullptr)
+ {
+ return true;
+ }
+
+ queueReplacement(rewritten, OriginalNode::IS_DROPPED);
+
+ // Don't iterate as the expression is rewritten.
+ return false;
+ }
+
+ // Same implementation as in RewriteExpressionTraverser. That traverser cannot replace root.
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ ASSERT(mStructureUniformMap.find(&node->variable()) == mStructureUniformMap.end());
+ }
+
+ private:
+ // Removes all samplers from a struct specifier.
+ void stripStructSpecifierSamplers(const TStructure *structure, TIntermSequence *newSequence)
+ {
+ TFieldList *newFieldList = new TFieldList;
+ ASSERT(structure->containsSamplers());
+
+ // Add this struct to the struct map
+ ASSERT(mStructureMap.find(structure) == mStructureMap.end());
+ StructureData *modifiedData = &mStructureMap[structure];
+
+ modifiedData->modified = nullptr;
+ modifiedData->fieldMap.resize(structure->fields().size(), std::numeric_limits<int>::max());
+
+ for (size_t fieldIndex = 0; fieldIndex < structure->fields().size(); ++fieldIndex)
+ {
+ const TField *field = structure->fields()[fieldIndex];
+ const TType &fieldType = *field->type();
+
+ // If the field is a sampler, or a struct that's entirely removed, skip it.
+ if (!fieldType.isSampler() && !isRemovedStructType(fieldType))
+ {
+ TType *newType = nullptr;
+
+ // Otherwise, if it's a struct that's replaced, create a new field of the replaced
+ // type.
+ if (fieldType.isStructureContainingSamplers())
+ {
+ const TStructure *fieldStruct = fieldType.getStruct();
+ ASSERT(mStructureMap.find(fieldStruct) != mStructureMap.end());
+
+ const TStructure *modifiedStruct = mStructureMap[fieldStruct].modified;
+ ASSERT(modifiedStruct);
+
+ newType = new TType(modifiedStruct, true);
+ if (fieldType.isArray())
+ {
+ newType->makeArrays(fieldType.getArraySizes());
+ }
+ }
+ else
+ {
+ // If not, duplicate the field as is.
+ newType = new TType(fieldType);
+ }
+
+ // Record the mapping of the field indices, so future EOpIndexDirectStruct's into
+ // this struct can be fixed up.
+ modifiedData->fieldMap[fieldIndex] = static_cast<int>(newFieldList->size());
+
+ TField *newField =
+ new TField(newType, field->name(), field->line(), field->symbolType());
+ newFieldList->push_back(newField);
+ }
+ }
+
+ // Prune empty structs.
+ if (newFieldList->empty())
+ {
+ return;
+ }
+
+ // Declare a new struct with the same name and the new fields.
+ modifiedData->modified =
+ new TStructure(mSymbolTable, structure->name(), newFieldList, structure->symbolType());
+ TType *newStructType = new TType(modifiedData->modified, true);
+ TVariable *newStructVar =
+ new TVariable(mSymbolTable, kEmptyImmutableString, newStructType, SymbolType::Empty);
+ TIntermSymbol *newStructRef = new TIntermSymbol(newStructVar);
+
+ TIntermDeclaration *structDecl = new TIntermDeclaration;
+ structDecl->appendDeclarator(newStructRef);
+
+ newSequence->push_back(structDecl);
+ }
+
+ // Returns true if the type is a struct that was removed because we extracted all the members.
+ bool isRemovedStructType(const TType &type) const
+ {
+ const TStructure *structure = type.getStruct();
+ if (structure == nullptr)
+ {
+ // Not a struct
+ return false;
+ }
+
+ // A struct is removed if it is in the map, but doesn't have a replacement struct.
+ auto iter = mStructureMap.find(structure);
+ return iter != mStructureMap.end() && iter->second.modified == nullptr;
+ }
+
+ // Removes samplers from struct uniforms. For each sampler removed also adds a new globally
+ // defined sampler uniform.
+ void extractStructSamplerUniforms(const TVariable &variable,
+ const TStructure *structure,
+ TIntermSequence *newSequence)
+ {
+ ASSERT(structure->containsSamplers());
+ ASSERT(mStructureMap.find(structure) != mStructureMap.end());
+
+ const TType &type = variable.getType();
+ enterArray(type);
+
+ for (const TField *field : structure->fields())
+ {
+ extractFieldSamplers(variable.name().data(), field, newSequence);
+ }
+
+ // If there's a replacement structure (because there are non-sampler fields in the struct),
+ // add a declaration with that type.
+ const TStructure *modified = mStructureMap[structure].modified;
+ if (modified != nullptr)
+ {
+ TType *newType = new TType(modified, false);
+ if (type.isArray())
+ {
+ newType->makeArrays(type.getArraySizes());
+ }
+ newType->setQualifier(EvqUniform);
+ const TVariable *newVariable =
+ new TVariable(mSymbolTable, variable.name(), newType, variable.symbolType());
+
+ TIntermDeclaration *newDecl = new TIntermDeclaration();
+ newDecl->appendDeclarator(new TIntermSymbol(newVariable));
+
+ newSequence->push_back(newDecl);
+
+ ASSERT(mStructureUniformMap.find(&variable) == mStructureUniformMap.end());
+ mStructureUniformMap[&variable] = newVariable;
+ }
+ else
+ {
+ mRemovedUniformsCount++;
+ }
+
+ exitArray(type);
+ }
+
+ // Extracts samplers from a field of a struct. Works with nested structs and arrays.
+ void extractFieldSamplers(const std::string &prefix,
+ const TField *field,
+ TIntermSequence *newSequence)
+ {
+ const TType &fieldType = *field->type();
+ if (fieldType.isSampler() || fieldType.isStructureContainingSamplers())
+ {
+ std::string newPrefix = prefix + "_" + field->name().data();
+
+ if (fieldType.isSampler())
+ {
+ extractSampler(newPrefix, fieldType, newSequence);
+ }
+ else
+ {
+ enterArray(fieldType);
+ const TStructure *structure = fieldType.getStruct();
+ for (const TField *nestedField : structure->fields())
+ {
+ extractFieldSamplers(newPrefix, nestedField, newSequence);
+ }
+ exitArray(fieldType);
+ }
+ }
+ }
+
+ void GenerateArraySizesFromStack(TVector<unsigned int> *sizesOut)
+ {
+ sizesOut->reserve(mArraySizeStack.size());
+
+ for (auto it = mArraySizeStack.rbegin(); it != mArraySizeStack.rend(); ++it)
+ {
+ sizesOut->push_back(*it);
+ }
+ }
+
+ // Extracts a sampler from a struct. Declares the new extracted sampler.
+ void extractSampler(const std::string &newName,
+ const TType &fieldType,
+ TIntermSequence *newSequence)
+ {
+ ASSERT(fieldType.isSampler());
+
+ TType *newType = new TType(fieldType);
+
+ // Add array dimensions accumulated so far due to struct arrays. Note that to support
+ // nested arrays, mArraySizeStack has the outermost size in the front. |makeArrays| thus
+ // expects this in reverse order.
+ TVector<unsigned int> parentArraySizes;
+ GenerateArraySizesFromStack(&parentArraySizes);
+ newType->makeArrays(parentArraySizes);
+
+ ImmutableStringBuilder nameBuilder(newName.size() + 1);
+ nameBuilder << newName;
+
+ newType->setQualifier(EvqUniform);
+ TVariable *newVariable =
+ new TVariable(mSymbolTable, nameBuilder, newType, SymbolType::AngleInternal);
+ TIntermSymbol *newSymbol = new TIntermSymbol(newVariable);
+
+ TIntermDeclaration *samplerDecl = new TIntermDeclaration;
+ samplerDecl->appendDeclarator(newSymbol);
+
+ newSequence->push_back(samplerDecl);
+
+ // TODO: Use a temp name instead of generating a name as currently done. There is no
+ // guarantee that these generated names cannot clash. Create a mapping from the previous
+ // name to the name assigned to the temp variable so ShaderVariable::mappedName can be
+ // updated post-transformation. http://anglebug.com/4301
+ ASSERT(mExtractedSamplers.find(newName) == mExtractedSamplers.end());
+ mExtractedSamplers[newName] = newVariable;
+ }
+
+ void enterArray(const TType &arrayType)
+ {
+ const TSpan<const unsigned int> &arraySizes = arrayType.getArraySizes();
+ for (auto it = arraySizes.rbegin(); it != arraySizes.rend(); ++it)
+ {
+ unsigned int arraySize = *it;
+ mArraySizeStack.push_back(arraySize);
+ }
+ }
+
+ void exitArray(const TType &arrayType)
+ {
+ mArraySizeStack.resize(mArraySizeStack.size() - arrayType.getNumArraySizes());
+ }
+
+ TCompiler *mCompiler;
+ int mRemovedUniformsCount;
+
+ // Map structures with samplers to ones that have their samplers removed.
+ StructureMap mStructureMap;
+
+ // Map uniform variables of structure type that are replaced with another variable.
+ StructureUniformMap mStructureUniformMap;
+
+ // Map a constructed sampler name to its variable. Used to replace an expression that uses this
+ // sampler with the extracted one.
+ ExtractedSamplerMap mExtractedSamplers;
+
+ // A stack of array sizes. Used to figure out the array dimensions of the extracted sampler,
+ // for example when it's nested in an array of structs in an array of structs.
+ TVector<unsigned int> mArraySizeStack;
+};
+} // anonymous namespace
+
+bool RewriteStructSamplers(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ int *removedUniformsCountOut)
+{
+ RewriteStructSamplersTraverser traverser(compiler, symbolTable);
+ root->traverse(&traverser);
+ *removedUniformsCountOut = traverser.removedUniformsCount();
+ return traverser.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.h
new file mode 100644
index 0000000000..f4c73a27fc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteStructSamplers: Extract structs from samplers.
+//
+// This traverser is designed to strip out samplers from structs. It moves them into separate
+// uniform sampler declarations. This allows the struct to be stored in the default uniform block.
+// This transformation requires MonomorphizeUnsupportedFunctions to have been run so it
+// wouldn't need to deal with functions that are passed such structs.
+//
+// For example:
+// struct S { sampler2D samp; int i; };
+// uniform S uni;
+// Is rewritten as:
+// struct S { int i; };
+// uniform S uni;
+// uniform sampler2D uni_i;
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITESTRUCTSAMPLERS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITESTRUCTSAMPLERS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteStructSamplers(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ int *removedUniformsCountOut);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_VULKAN_REWRITESTRUCTSAMPLERS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp
new file mode 100644
index 0000000000..71284ecc1b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp
@@ -0,0 +1,168 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Implementation of texelFetchOffset translation issue workaround.
+// See header for more info.
+
+#include "compiler/translator/tree_ops/RewriteTexelFetchOffset.h"
+
+#include "common/angleutils.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class Traverser : public TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool Apply(TCompiler *compiler,
+ TIntermNode *root,
+ const TSymbolTable &symbolTable,
+ int shaderVersion);
+
+ private:
+ Traverser(const TSymbolTable &symbolTable, int shaderVersion);
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ void nextIteration();
+
+ const TSymbolTable *symbolTable;
+ const int shaderVersion;
+ bool mFound = false;
+};
+
+Traverser::Traverser(const TSymbolTable &symbolTable, int shaderVersion)
+ : TIntermTraverser(true, false, false), symbolTable(&symbolTable), shaderVersion(shaderVersion)
+{}
+
+// static
+bool Traverser::Apply(TCompiler *compiler,
+ TIntermNode *root,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ Traverser traverser(symbolTable, shaderVersion);
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.mFound)
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.mFound);
+
+ return true;
+}
+
+void Traverser::nextIteration()
+{
+ mFound = false;
+}
+
+bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ if (mFound)
+ {
+ return false;
+ }
+
+ // Decide if the node represents the call of texelFetchOffset.
+ if (!BuiltInGroup::IsBuiltIn(node->getOp()))
+ {
+ return true;
+ }
+
+ ASSERT(node->getFunction()->symbolType() == SymbolType::BuiltIn);
+ if (node->getFunction()->name() != "texelFetchOffset")
+ {
+ return true;
+ }
+
+ // Potential problem case detected, apply workaround.
+ const TIntermSequence *sequence = node->getSequence();
+ ASSERT(sequence->size() == 4u);
+
+ // Decide if the sampler is a 2DArray sampler. In that case position is ivec3 and offset is
+ // ivec2.
+ bool is2DArray = sequence->at(1)->getAsTyped()->getNominalSize() == 3 &&
+ sequence->at(3)->getAsTyped()->getNominalSize() == 2;
+
+ // Create new node that represents the call of function texelFetch.
+ // Its argument list will be: texelFetch(sampler, Position+offset, lod).
+
+ TIntermSequence texelFetchArguments;
+
+ // sampler
+ texelFetchArguments.push_back(sequence->at(0));
+
+ // Position
+ TIntermTyped *texCoordNode = sequence->at(1)->getAsTyped();
+ ASSERT(texCoordNode);
+
+ // offset
+ TIntermTyped *offsetNode = nullptr;
+ ASSERT(sequence->at(3)->getAsTyped());
+ if (is2DArray)
+ {
+ // For 2DArray samplers, Position is ivec3 and offset is ivec2;
+ // So offset must be converted into an ivec3 before being added to Position.
+ TIntermSequence constructOffsetIvecArguments;
+ constructOffsetIvecArguments.push_back(sequence->at(3)->getAsTyped());
+
+ TIntermTyped *zeroNode = CreateZeroNode(TType(EbtInt));
+ constructOffsetIvecArguments.push_back(zeroNode);
+
+ offsetNode = TIntermAggregate::CreateConstructor(texCoordNode->getType(),
+ &constructOffsetIvecArguments);
+ offsetNode->setLine(texCoordNode->getLine());
+ }
+ else
+ {
+ offsetNode = sequence->at(3)->getAsTyped();
+ }
+
+ // Position+offset
+ TIntermBinary *add = new TIntermBinary(EOpAdd, texCoordNode, offsetNode);
+ add->setLine(texCoordNode->getLine());
+ texelFetchArguments.push_back(add);
+
+ // lod
+ texelFetchArguments.push_back(sequence->at(2));
+
+ ASSERT(texelFetchArguments.size() == 3u);
+
+ TIntermTyped *texelFetchNode = CreateBuiltInFunctionCallNode("texelFetch", &texelFetchArguments,
+ *symbolTable, shaderVersion);
+ texelFetchNode->setLine(node->getLine());
+
+ // Replace the old node by this new node.
+ queueReplacement(texelFetchNode, OriginalNode::IS_DROPPED);
+ mFound = true;
+ return false;
+}
+
+} // anonymous namespace
+
+bool RewriteTexelFetchOffset(TCompiler *compiler,
+ TIntermNode *root,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ // texelFetchOffset is only valid in GLSL 3.0 and later.
+ if (shaderVersion < 300)
+ return true;
+
+ return Traverser::Apply(compiler, root, symbolTable, shaderVersion);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.h
new file mode 100644
index 0000000000..c2c3c07aad
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.h
@@ -0,0 +1,34 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This mutating tree traversal works around an issue on the translation
+// from texelFetchOffset into HLSL function Load on INTEL drivers. It
+// works by translating texelFetchOffset into texelFetch:
+//
+// - From: texelFetchOffset(sampler, Position, lod, offset)
+// - To: texelFetch(sampler, Position+offset, lod)
+//
+// See http://anglebug.com/1469
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITE_TEXELFETCHOFFSET_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITE_TEXELFETCHOFFSET_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteTexelFetchOffset(TCompiler *compiler,
+ TIntermNode *root,
+ const TSymbolTable &symbolTable,
+ int shaderVersion);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITE_TEXELFETCHOFFSET_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp
new file mode 100644
index 0000000000..4eab90e4fa
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp
@@ -0,0 +1,223 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Scalarize vector and matrix constructor args, so that vectors built from components don't have
+// matrix arguments, and matrices built from components don't have vector arguments. This avoids
+// driver bugs around vector and matrix constructors.
+//
+
+#include "compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h"
+#include "common/debug.h"
+
+#include <algorithm>
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+TIntermBinary *ConstructVectorIndexBinaryNode(TIntermTyped *symbolNode, int index)
+{
+ return new TIntermBinary(EOpIndexDirect, symbolNode, CreateIndexNode(index));
+}
+
+TIntermBinary *ConstructMatrixIndexBinaryNode(TIntermTyped *symbolNode, int colIndex, int rowIndex)
+{
+ TIntermBinary *colVectorNode = ConstructVectorIndexBinaryNode(symbolNode, colIndex);
+
+ return new TIntermBinary(EOpIndexDirect, colVectorNode, CreateIndexNode(rowIndex));
+}
+
+class ScalarizeArgsTraverser : public TIntermTraverser
+{
+ public:
+ ScalarizeArgsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mNodesToScalarize(IntermNodePatternMatcher::kScalarizedVecOrMatConstructor)
+ {}
+
+ protected:
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+
+ private:
+ void scalarizeArgs(TIntermAggregate *aggregate, bool scalarizeVector, bool scalarizeMatrix);
+
+ // If we have the following code:
+ // mat4 m(0);
+ // vec4 v(1, m);
+ // We will rewrite to:
+ // mat4 m(0);
+ // mat4 s0 = m;
+ // vec4 v(1, s0[0][0], s0[0][1], s0[0][2]);
+ // This function is to create nodes for "mat4 s0 = m;" and insert it to the code sequence. This
+ // way the possible side effects of the constructor argument will only be evaluated once.
+ TIntermTyped *createTempVariable(TIntermTyped *original);
+
+ std::vector<TIntermSequence> mBlockStack;
+
+ IntermNodePatternMatcher mNodesToScalarize;
+};
+
+bool ScalarizeArgsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ ASSERT(visit == PreVisit);
+ if (mNodesToScalarize.match(node, getParentNode()))
+ {
+ if (node->getType().isVector())
+ {
+ scalarizeArgs(node, false, true);
+ }
+ else
+ {
+ ASSERT(node->getType().isMatrix());
+ scalarizeArgs(node, true, false);
+ }
+ }
+ return true;
+}
+
+bool ScalarizeArgsTraverser::visitBlock(Visit visit, TIntermBlock *node)
+{
+ mBlockStack.push_back(TIntermSequence());
+ {
+ for (TIntermNode *child : *node->getSequence())
+ {
+ ASSERT(child != nullptr);
+ child->traverse(this);
+ mBlockStack.back().push_back(child);
+ }
+ }
+ if (mBlockStack.back().size() > node->getSequence()->size())
+ {
+ node->getSequence()->clear();
+ *(node->getSequence()) = mBlockStack.back();
+ }
+ mBlockStack.pop_back();
+ return false;
+}
+
+void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
+ bool scalarizeVector,
+ bool scalarizeMatrix)
+{
+ ASSERT(aggregate);
+ ASSERT(!aggregate->isArray());
+ int size = static_cast<int>(aggregate->getType().getObjectSize());
+ TIntermSequence *sequence = aggregate->getSequence();
+ TIntermSequence originalArgs(*sequence);
+ sequence->clear();
+ for (TIntermNode *originalArgNode : originalArgs)
+ {
+ ASSERT(size > 0);
+ TIntermTyped *originalArg = originalArgNode->getAsTyped();
+ ASSERT(originalArg);
+ TIntermTyped *argVariable = createTempVariable(originalArg);
+ if (originalArg->isScalar())
+ {
+ sequence->push_back(argVariable);
+ size--;
+ }
+ else if (originalArg->isVector())
+ {
+ if (scalarizeVector)
+ {
+ int repeat = std::min<int>(size, originalArg->getNominalSize());
+ size -= repeat;
+ for (int index = 0; index < repeat; ++index)
+ {
+ TIntermBinary *newNode =
+ ConstructVectorIndexBinaryNode(argVariable->deepCopy(), index);
+ sequence->push_back(newNode);
+ }
+ }
+ else
+ {
+ sequence->push_back(argVariable);
+ size -= originalArg->getNominalSize();
+ }
+ }
+ else
+ {
+ ASSERT(originalArg->isMatrix());
+ if (scalarizeMatrix)
+ {
+ int colIndex = 0, rowIndex = 0;
+ int repeat = std::min<int>(size, originalArg->getCols() * originalArg->getRows());
+ size -= repeat;
+ while (repeat > 0)
+ {
+ TIntermBinary *newNode =
+ ConstructMatrixIndexBinaryNode(argVariable->deepCopy(), colIndex, rowIndex);
+ sequence->push_back(newNode);
+ rowIndex++;
+ if (rowIndex >= originalArg->getRows())
+ {
+ rowIndex = 0;
+ colIndex++;
+ }
+ repeat--;
+ }
+ }
+ else
+ {
+ sequence->push_back(argVariable);
+ size -= originalArg->getCols() * originalArg->getRows();
+ }
+ }
+ }
+}
+
+TIntermTyped *ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
+{
+ ASSERT(original);
+
+ TType *type = new TType(original->getType());
+ type->setQualifier(EvqTemporary);
+
+ // The precision of the constant must have been retained (or derived), which will now apply to
+ // the temp variable. In some cases, the precision cannot be derived, so use the constant as
+ // is. For example, in the following standalone statement, the precision of the constant 0
+ // cannot be determined:
+ //
+ // mat2(0, bvec3(m));
+ //
+ if (IsPrecisionApplicableToType(type->getBasicType()) && type->getPrecision() == EbpUndefined)
+ {
+ return original;
+ }
+
+ TVariable *variable = CreateTempVariable(mSymbolTable, type);
+
+ ASSERT(mBlockStack.size() > 0);
+ TIntermSequence &sequence = mBlockStack.back();
+ TIntermDeclaration *declaration = CreateTempInitDeclarationNode(variable, original);
+ sequence.push_back(declaration);
+
+ return CreateTempSymbolNode(variable);
+}
+
+} // namespace
+
+bool ScalarizeVecAndMatConstructorArgs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ ScalarizeArgsTraverser scalarizer(symbolTable);
+ root->traverse(&scalarizer);
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h
new file mode 100644
index 0000000000..617cbd7682
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Scalarize vector and matrix constructor args, so that vectors built from components don't have
+// matrix arguments, and matrices built from components don't have vector arguments. This avoids
+// driver bugs around vector and matrix constructors.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool ScalarizeVecAndMatConstructorArgs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp
new file mode 100644
index 0000000000..6d48449154
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp
@@ -0,0 +1,199 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The SeparateDeclarations function processes declarations, so that in the end each declaration
+// contains only one declarator.
+// This is useful as an intermediate step when initialization needs to be separated from
+// declaration, or when things need to be unfolded out of the initializer.
+// Example:
+// int a[1] = int[1](1), b[1] = int[1](2);
+// gets transformed when run through this class into the AST equivalent of:
+// int a[1] = int[1](1);
+// int b[1] = int[1](2);
+
+#include "compiler/translator/tree_ops/SeparateDeclarations.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class SeparateDeclarationsTraverser : private TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool apply(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+ private:
+ SeparateDeclarationsTraverser(TSymbolTable *symbolTable);
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ void visitSymbol(TIntermSymbol *symbol) override;
+
+ void separateDeclarator(TIntermSequence *sequence,
+ size_t index,
+ TIntermSequence *replacementDeclarations,
+ const TStructure **replacementStructure);
+
+ VariableReplacementMap mVariableMap;
+};
+
+bool SeparateDeclarationsTraverser::apply(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ SeparateDeclarationsTraverser separateDecl(symbolTable);
+ root->traverse(&separateDecl);
+ return separateDecl.updateTree(compiler, root);
+}
+
+SeparateDeclarationsTraverser::SeparateDeclarationsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable)
+{}
+
+bool SeparateDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ TIntermSequence *sequence = node->getSequence();
+ if (sequence->size() <= 1)
+ {
+ return true;
+ }
+
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ ASSERT(parentBlock != nullptr);
+
+ TIntermSequence replacementDeclarations;
+ const TStructure *replacementStructure = nullptr;
+ for (size_t ii = 0; ii < sequence->size(); ++ii)
+ {
+ separateDeclarator(sequence, ii, &replacementDeclarations, &replacementStructure);
+ }
+
+ mMultiReplacements.emplace_back(parentBlock, node, std::move(replacementDeclarations));
+ return false;
+}
+
+void SeparateDeclarationsTraverser::visitSymbol(TIntermSymbol *symbol)
+{
+ const TVariable *variable = &symbol->variable();
+ if (mVariableMap.count(variable) > 0)
+ {
+ queueAccessChainReplacement(mVariableMap[variable]->deepCopy());
+ }
+}
+
+void SeparateDeclarationsTraverser::separateDeclarator(TIntermSequence *sequence,
+ size_t index,
+ TIntermSequence *replacementDeclarations,
+ const TStructure **replacementStructure)
+{
+ TIntermTyped *declarator = sequence->at(index)->getAsTyped();
+ const TType &declaratorType = declarator->getType();
+
+ // If the declaration is not simultaneously declaring a struct, can use the same declarator.
+ // Otherwise, the first declarator is taken as-is if the struct has a name.
+ const TStructure *structure = declaratorType.getStruct();
+ const bool isStructSpecifier = declaratorType.isStructSpecifier();
+ if (!isStructSpecifier || (index == 0 && structure->symbolType() != SymbolType::Empty))
+ {
+ TIntermDeclaration *replacementDeclaration = new TIntermDeclaration;
+
+ // Make sure to update the declarator's initializers if any.
+ declarator->traverse(this);
+
+ replacementDeclaration->appendDeclarator(declarator);
+ replacementDeclaration->setLine(declarator->getLine());
+ replacementDeclarations->push_back(replacementDeclaration);
+ return;
+ }
+
+ // If the struct is nameless, split it out first.
+ if (structure->symbolType() == SymbolType::Empty)
+ {
+ if (*replacementStructure == nullptr)
+ {
+ TStructure *newStructure =
+ new TStructure(mSymbolTable, kEmptyImmutableString, &structure->fields(),
+ SymbolType::AngleInternal);
+ newStructure->setAtGlobalScope(structure->atGlobalScope());
+ *replacementStructure = structure = newStructure;
+
+ TType *namedType = new TType(structure, true);
+ namedType->setQualifier(EvqGlobal);
+
+ TVariable *structVariable =
+ new TVariable(mSymbolTable, kEmptyImmutableString, namedType, SymbolType::Empty);
+
+ TIntermDeclaration *structDeclaration = new TIntermDeclaration;
+ structDeclaration->appendDeclarator(new TIntermSymbol(structVariable));
+ structDeclaration->setLine(declarator->getLine());
+ replacementDeclarations->push_back(structDeclaration);
+ }
+ else
+ {
+ structure = *replacementStructure;
+ }
+ }
+
+ // Redeclare the declarator but not as a struct specifier.
+ TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
+ TIntermTyped *initializer = nullptr;
+ if (asSymbol == nullptr)
+ {
+ TIntermBinary *asBinary = declarator->getAsBinaryNode();
+ ASSERT(asBinary->getOp() == EOpInitialize);
+ asSymbol = asBinary->getLeft()->getAsSymbolNode();
+ initializer = asBinary->getRight();
+
+ // Make sure the initializer itself has its variables replaced if necessary.
+ if (initializer->getAsSymbolNode())
+ {
+ const TVariable *initializerVariable = &initializer->getAsSymbolNode()->variable();
+ if (mVariableMap.count(initializerVariable) > 0)
+ {
+ initializer = mVariableMap[initializerVariable]->deepCopy();
+ }
+ }
+ else
+ {
+ initializer->traverse(this);
+ }
+ }
+
+ ASSERT(asSymbol && asSymbol->variable().symbolType() != SymbolType::Empty);
+
+ TType *newType = new TType(structure, false);
+ newType->setQualifier(asSymbol->getType().getQualifier());
+ newType->makeArrays(asSymbol->getType().getArraySizes());
+
+ TVariable *replacementVar = new TVariable(mSymbolTable, asSymbol->getName(), newType,
+ asSymbol->variable().symbolType());
+ TIntermSymbol *replacementSymbol = new TIntermSymbol(replacementVar);
+ TIntermTyped *replacement = replacementSymbol;
+ if (initializer)
+ {
+ replacement = new TIntermBinary(EOpInitialize, replacement, initializer);
+ }
+
+ TIntermDeclaration *replacementDeclaration = new TIntermDeclaration;
+ replacementDeclaration->appendDeclarator(replacement);
+ replacementDeclaration->setLine(declarator->getLine());
+ replacementDeclarations->push_back(replacementDeclaration);
+
+ mVariableMap[&asSymbol->variable()] = replacementSymbol;
+}
+} // namespace
+
+bool SeparateDeclarations(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ return SeparateDeclarationsTraverser::apply(compiler, root, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.h
new file mode 100644
index 0000000000..5f55162ef4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The SeparateDeclarations function processes declarations, so that in the end each declaration
+// contains only one declarator.
+// This is useful as an intermediate step when initialization needs to be separated from
+// declaration, or when things need to be unfolded out of the initializer.
+// Example:
+// int a[1] = int[1](1), b[1] = int[1](2);
+// gets transformed when run through this class into the AST equivalent of:
+// int a[1] = int[1](1);
+// int b[1] = int[1](2);
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_SEPARATEDECLARATIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SEPARATEDECLARATIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool SeparateDeclarations(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_SEPARATEDECLARATIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.cpp
new file mode 100644
index 0000000000..fb3f4ba1c1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.cpp
@@ -0,0 +1,115 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SeparateStructFromUniformDeclarations: Separate struct declarations from uniform declarations.
+//
+
+#include "compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+// This traverser translates embedded uniform structs into a specifier and declaration.
+// This makes the declarations easier to move into uniform blocks.
+class Traverser : public TIntermTraverser
+{
+ public:
+ explicit Traverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *decl) override
+ {
+ ASSERT(visit == PreVisit);
+
+ if (!mInGlobalScope)
+ {
+ return true;
+ }
+
+ const TIntermSequence &sequence = *(decl->getSequence());
+ ASSERT(sequence.size() == 1);
+ TIntermTyped *declarator = sequence.front()->getAsTyped();
+ const TType &type = declarator->getType();
+
+ if (type.isStructSpecifier() && type.getQualifier() == EvqUniform)
+ {
+ doReplacement(decl, declarator, type);
+ return false;
+ }
+
+ return true;
+ }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ const TVariable *variable = &symbol->variable();
+ if (mVariableMap.count(variable) > 0)
+ {
+ queueAccessChainReplacement(mVariableMap[variable]->deepCopy());
+ }
+ }
+
+ private:
+ void doReplacement(TIntermDeclaration *decl, TIntermTyped *declarator, const TType &oldType)
+ {
+ const TStructure *structure = oldType.getStruct();
+ if (structure->symbolType() == SymbolType::Empty)
+ {
+ // Handle nameless structs: uniform struct { ... } variable;
+ structure = new TStructure(mSymbolTable, kEmptyImmutableString, &structure->fields(),
+ SymbolType::AngleInternal);
+ }
+ TType *namedType = new TType(structure, true);
+ namedType->setQualifier(EvqGlobal);
+
+ TVariable *structVariable =
+ new TVariable(mSymbolTable, kEmptyImmutableString, namedType, SymbolType::Empty);
+ TIntermSymbol *structDeclarator = new TIntermSymbol(structVariable);
+ TIntermDeclaration *structDeclaration = new TIntermDeclaration;
+ structDeclaration->appendDeclarator(structDeclarator);
+
+ TIntermSequence newSequence;
+ newSequence.push_back(structDeclaration);
+
+ // Redeclare the uniform with the (potentially) new struct type
+ TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
+ ASSERT(asSymbol && asSymbol->variable().symbolType() != SymbolType::Empty);
+
+ TIntermDeclaration *namedDecl = new TIntermDeclaration;
+ TType *uniformType = new TType(structure, false);
+ uniformType->setQualifier(EvqUniform);
+ uniformType->makeArrays(oldType.getArraySizes());
+
+ TVariable *newVar = new TVariable(mSymbolTable, asSymbol->getName(), uniformType,
+ asSymbol->variable().symbolType());
+ TIntermSymbol *newSymbol = new TIntermSymbol(newVar);
+ namedDecl->appendDeclarator(newSymbol);
+
+ newSequence.push_back(namedDecl);
+
+ mVariableMap[&asSymbol->variable()] = newSymbol;
+
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), decl,
+ std::move(newSequence));
+ }
+
+ VariableReplacementMap mVariableMap;
+};
+} // anonymous namespace
+
+bool SeparateStructFromUniformDeclarations(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ Traverser separateStructDecls(symbolTable);
+ root->traverse(&separateStructDecls);
+ return separateStructDecls.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h
new file mode 100644
index 0000000000..424a742e54
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h
@@ -0,0 +1,39 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SeparateStructFromUniformDeclarations: Separate struct declarations from uniform declarations.
+// It necessarily gives nameless uniform structs internal names.
+//
+// For example:
+// uniform struct { int a; } uni;
+// becomes:
+// struct s1 { int a; };
+// uniform s1 uni;
+//
+// And:
+// uniform struct S { int a; } uni;
+// becomes:
+// struct S { int a; };
+// uniform S uni;
+//
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_SEPARATESTRUCTFROMUNIFORMDECLARATIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SEPARATESTRUCTFROMUNIFORMDECLARATIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool SeparateStructFromUniformDeclarations(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_SEPARATESTRUCTFROMUNIFORMDECLARATIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp
new file mode 100644
index 0000000000..c6a3e0b9ee
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp
@@ -0,0 +1,499 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SimplifyLoopConditions is an AST traverser that converts loop conditions and loop expressions
+// to regular statements inside the loop. This way further transformations that generate statements
+// from loop conditions and loop expressions work correctly.
+//
+
+#include "compiler/translator/tree_ops/SimplifyLoopConditions.h"
+
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+struct LoopInfo
+{
+ const TVariable *conditionVariable = nullptr;
+ TIntermTyped *condition = nullptr;
+ TIntermTyped *expression = nullptr;
+};
+
+class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser
+{
+ public:
+ SimplifyLoopConditionsTraverser(const IntermNodePatternMatcher *conditionsToSimplify,
+ TSymbolTable *symbolTable);
+
+ void traverseLoop(TIntermLoop *node) override;
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitTernary(Visit visit, TIntermTernary *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitBranch(Visit visit, TIntermBranch *node) override;
+
+ bool foundLoopToChange() const { return mFoundLoopToChange; }
+
+ protected:
+ // Marked to true once an operation that needs to be hoisted out of a loop expression has been
+ // found.
+ bool mFoundLoopToChange;
+ bool mInsideLoopInitConditionOrExpression;
+ const IntermNodePatternMatcher *mConditionsToSimplify;
+
+ private:
+ LoopInfo mLoop;
+};
+
+SimplifyLoopConditionsTraverser::SimplifyLoopConditionsTraverser(
+ const IntermNodePatternMatcher *conditionsToSimplify,
+ TSymbolTable *symbolTable)
+ : TLValueTrackingTraverser(true, false, false, symbolTable),
+ mFoundLoopToChange(false),
+ mInsideLoopInitConditionOrExpression(false),
+ mConditionsToSimplify(conditionsToSimplify)
+{}
+
+// If we're inside a loop initialization, condition, or expression, we check for expressions that
+// should be moved out of the loop condition or expression. If one is found, the loop is
+// transformed.
+// If we're not inside loop initialization, condition, or expression, we only need to traverse nodes
+// that may contain loops.
+
+bool SimplifyLoopConditionsTraverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ if (!mInsideLoopInitConditionOrExpression)
+ return false;
+
+ if (mFoundLoopToChange)
+ return false; // Already decided to change this loop.
+
+ ASSERT(mConditionsToSimplify);
+ mFoundLoopToChange = mConditionsToSimplify->match(node);
+ return !mFoundLoopToChange;
+}
+
+bool SimplifyLoopConditionsTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (!mInsideLoopInitConditionOrExpression)
+ return false;
+
+ if (mFoundLoopToChange)
+ return false; // Already decided to change this loop.
+
+ ASSERT(mConditionsToSimplify);
+ mFoundLoopToChange =
+ mConditionsToSimplify->match(node, getParentNode(), isLValueRequiredHere());
+ return !mFoundLoopToChange;
+}
+
+bool SimplifyLoopConditionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ if (!mInsideLoopInitConditionOrExpression)
+ return false;
+
+ if (mFoundLoopToChange)
+ return false; // Already decided to change this loop.
+
+ ASSERT(mConditionsToSimplify);
+ mFoundLoopToChange = mConditionsToSimplify->match(node, getParentNode());
+ return !mFoundLoopToChange;
+}
+
+bool SimplifyLoopConditionsTraverser::visitTernary(Visit visit, TIntermTernary *node)
+{
+ if (!mInsideLoopInitConditionOrExpression)
+ return false;
+
+ if (mFoundLoopToChange)
+ return false; // Already decided to change this loop.
+
+ ASSERT(mConditionsToSimplify);
+ mFoundLoopToChange = mConditionsToSimplify->match(node);
+ return !mFoundLoopToChange;
+}
+
+bool SimplifyLoopConditionsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ if (!mInsideLoopInitConditionOrExpression)
+ return false;
+
+ if (mFoundLoopToChange)
+ return false; // Already decided to change this loop.
+
+ ASSERT(mConditionsToSimplify);
+ mFoundLoopToChange = mConditionsToSimplify->match(node);
+ return !mFoundLoopToChange;
+}
+
+bool SimplifyLoopConditionsTraverser::visitBranch(Visit visit, TIntermBranch *node)
+{
+ if (node->getFlowOp() == EOpContinue && (mLoop.condition || mLoop.expression))
+ {
+ TIntermBlock *parent = getParentNode()->getAsBlock();
+ ASSERT(parent);
+ TIntermSequence seq;
+ if (mLoop.expression)
+ {
+ seq.push_back(mLoop.expression->deepCopy());
+ }
+ if (mLoop.condition)
+ {
+ ASSERT(mLoop.conditionVariable);
+ seq.push_back(
+ CreateTempAssignmentNode(mLoop.conditionVariable, mLoop.condition->deepCopy()));
+ }
+ seq.push_back(node);
+ mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parent, node, std::move(seq)));
+ }
+
+ return true;
+}
+
+TIntermBlock *CreateFromBody(TIntermLoop *node, bool *bodyEndsInBranchOut)
+{
+ TIntermBlock *newBody = new TIntermBlock();
+ *bodyEndsInBranchOut = false;
+
+ TIntermBlock *nodeBody = node->getBody();
+ if (nodeBody != nullptr)
+ {
+ newBody->getSequence()->push_back(nodeBody);
+ *bodyEndsInBranchOut = EndsInBranch(nodeBody);
+ }
+ return newBody;
+}
+
+void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
+{
+ // Mark that we're inside a loop condition or expression, and determine if the loop needs to be
+ // transformed.
+
+ ScopedNodeInTraversalPath addToPath(this, node);
+
+ mInsideLoopInitConditionOrExpression = true;
+ mFoundLoopToChange = !mConditionsToSimplify;
+
+ if (!mFoundLoopToChange && node->getInit())
+ {
+ node->getInit()->traverse(this);
+ }
+
+ if (!mFoundLoopToChange && node->getCondition())
+ {
+ node->getCondition()->traverse(this);
+ }
+
+ if (!mFoundLoopToChange && node->getExpression())
+ {
+ node->getExpression()->traverse(this);
+ }
+
+ mInsideLoopInitConditionOrExpression = false;
+
+ const LoopInfo prevLoop = mLoop;
+
+ if (mFoundLoopToChange)
+ {
+ const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
+ mLoop.conditionVariable = CreateTempVariable(mSymbolTable, boolType);
+ mLoop.condition = node->getCondition();
+ mLoop.expression = node->getExpression();
+
+ // Replace the loop condition with a boolean variable that's updated on each iteration.
+ TLoopType loopType = node->getType();
+ if (loopType == ELoopWhile)
+ {
+ ASSERT(!mLoop.expression);
+
+ if (mLoop.condition->getAsSymbolNode())
+ {
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else if (mLoop.condition->getAsConstantUnion())
+ {
+ // Transform:
+ // while (expr) { body; }
+ // into
+ // bool s0 = expr;
+ // while (s0) { body; }
+ TIntermDeclaration *tempInitDeclaration =
+ CreateTempInitDeclarationNode(mLoop.conditionVariable, mLoop.condition);
+ insertStatementInParentBlock(tempInitDeclaration);
+
+ node->setCondition(CreateTempSymbolNode(mLoop.conditionVariable));
+
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else
+ {
+ // Transform:
+ // while (expr) { body; }
+ // into
+ // bool s0 = expr;
+ // while (s0) { { body; } s0 = expr; }
+ //
+ // Local case statements are transformed into:
+ // s0 = expr; continue;
+ TIntermDeclaration *tempInitDeclaration =
+ CreateTempInitDeclarationNode(mLoop.conditionVariable, mLoop.condition);
+ insertStatementInParentBlock(tempInitDeclaration);
+
+ bool bodyEndsInBranch;
+ TIntermBlock *newBody = CreateFromBody(node, &bodyEndsInBranch);
+ if (!bodyEndsInBranch)
+ {
+ newBody->getSequence()->push_back(CreateTempAssignmentNode(
+ mLoop.conditionVariable, mLoop.condition->deepCopy()));
+ }
+
+ // Can't use queueReplacement to replace old body, since it may have been nullptr.
+ // It's safe to do the replacements in place here - the new body will still be
+ // traversed, but that won't create any problems.
+ node->setBody(newBody);
+ node->setCondition(CreateTempSymbolNode(mLoop.conditionVariable));
+ }
+ }
+ else if (loopType == ELoopDoWhile)
+ {
+ ASSERT(!mLoop.expression);
+
+ if (mLoop.condition->getAsSymbolNode())
+ {
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else if (mLoop.condition->getAsConstantUnion())
+ {
+ // Transform:
+ // do {
+ // body;
+ // } while (expr);
+ // into
+ // bool s0 = expr;
+ // do {
+ // body;
+ // } while (s0);
+ TIntermDeclaration *tempInitDeclaration =
+ CreateTempInitDeclarationNode(mLoop.conditionVariable, mLoop.condition);
+ insertStatementInParentBlock(tempInitDeclaration);
+
+ node->setCondition(CreateTempSymbolNode(mLoop.conditionVariable));
+
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else
+ {
+ // Transform:
+ // do {
+ // body;
+ // } while (expr);
+ // into
+ // bool s0;
+ // do {
+ // { body; }
+ // s0 = expr;
+ // } while (s0);
+ // Local case statements are transformed into:
+ // s0 = expr; continue;
+ TIntermDeclaration *tempInitDeclaration =
+ CreateTempDeclarationNode(mLoop.conditionVariable);
+ insertStatementInParentBlock(tempInitDeclaration);
+
+ bool bodyEndsInBranch;
+ TIntermBlock *newBody = CreateFromBody(node, &bodyEndsInBranch);
+ if (!bodyEndsInBranch)
+ {
+ newBody->getSequence()->push_back(
+ CreateTempAssignmentNode(mLoop.conditionVariable, mLoop.condition));
+ }
+
+ // Can't use queueReplacement to replace old body, since it may have been nullptr.
+ // It's safe to do the replacements in place here - the new body will still be
+ // traversed, but that won't create any problems.
+ node->setBody(newBody);
+ node->setCondition(CreateTempSymbolNode(mLoop.conditionVariable));
+ }
+ }
+ else if (loopType == ELoopFor)
+ {
+ if (!mLoop.condition)
+ {
+ mLoop.condition = CreateBoolNode(true);
+ }
+
+ TIntermLoop *whileLoop;
+ TIntermBlock *loopScope = new TIntermBlock();
+ TIntermSequence *loopScopeSequence = loopScope->getSequence();
+
+ // Insert "init;"
+ if (node->getInit())
+ {
+ loopScopeSequence->push_back(node->getInit());
+ }
+
+ if (mLoop.condition->getAsSymbolNode())
+ {
+ // Move the loop condition inside the loop.
+ // Transform:
+ // for (init; expr; exprB) { body; }
+ // into
+ // {
+ // init;
+ // while (expr) {
+ // { body; }
+ // exprB;
+ // }
+ // }
+ //
+ // Local case statements are transformed into:
+ // exprB; continue;
+
+ // Insert "{ body; }" in the while loop
+ bool bodyEndsInBranch;
+ TIntermBlock *whileLoopBody = CreateFromBody(node, &bodyEndsInBranch);
+ // Insert "exprB;" in the while loop
+ if (!bodyEndsInBranch && node->getExpression())
+ {
+ whileLoopBody->getSequence()->push_back(node->getExpression());
+ }
+ // Create "while(expr) { whileLoopBody }"
+ whileLoop =
+ new TIntermLoop(ELoopWhile, nullptr, mLoop.condition, nullptr, whileLoopBody);
+
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else if (mLoop.condition->getAsConstantUnion())
+ {
+ // Move the loop condition inside the loop.
+ // Transform:
+ // for (init; expr; exprB) { body; }
+ // into
+ // {
+ // init;
+ // bool s0 = expr;
+ // while (s0) {
+ // { body; }
+ // exprB;
+ // }
+ // }
+ //
+ // Local case statements are transformed into:
+ // exprB; continue;
+
+ // Insert "bool s0 = expr;"
+ loopScopeSequence->push_back(
+ CreateTempInitDeclarationNode(mLoop.conditionVariable, mLoop.condition));
+ // Insert "{ body; }" in the while loop
+ bool bodyEndsInBranch;
+ TIntermBlock *whileLoopBody = CreateFromBody(node, &bodyEndsInBranch);
+ // Insert "exprB;" in the while loop
+ if (!bodyEndsInBranch && node->getExpression())
+ {
+ whileLoopBody->getSequence()->push_back(node->getExpression());
+ }
+ // Create "while(s0) { whileLoopBody }"
+ whileLoop = new TIntermLoop(ELoopWhile, nullptr,
+ CreateTempSymbolNode(mLoop.conditionVariable), nullptr,
+ whileLoopBody);
+
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else
+ {
+ // Move the loop condition inside the loop.
+ // Transform:
+ // for (init; expr; exprB) { body; }
+ // into
+ // {
+ // init;
+ // bool s0 = expr;
+ // while (s0) {
+ // { body; }
+ // exprB;
+ // s0 = expr;
+ // }
+ // }
+ //
+ // Local case statements are transformed into:
+ // exprB; s0 = expr; continue;
+
+ // Insert "bool s0 = expr;"
+ loopScopeSequence->push_back(
+ CreateTempInitDeclarationNode(mLoop.conditionVariable, mLoop.condition));
+ // Insert "{ body; }" in the while loop
+ bool bodyEndsInBranch;
+ TIntermBlock *whileLoopBody = CreateFromBody(node, &bodyEndsInBranch);
+ // Insert "exprB;" in the while loop
+ if (!bodyEndsInBranch && node->getExpression())
+ {
+ whileLoopBody->getSequence()->push_back(node->getExpression());
+ }
+ // Insert "s0 = expr;" in the while loop
+ if (!bodyEndsInBranch)
+ {
+ whileLoopBody->getSequence()->push_back(CreateTempAssignmentNode(
+ mLoop.conditionVariable, mLoop.condition->deepCopy()));
+ }
+ // Create "while(s0) { whileLoopBody }"
+ whileLoop = new TIntermLoop(ELoopWhile, nullptr,
+ CreateTempSymbolNode(mLoop.conditionVariable), nullptr,
+ whileLoopBody);
+ }
+
+ loopScope->getSequence()->push_back(whileLoop);
+ queueReplacement(loopScope, OriginalNode::IS_DROPPED);
+
+ // After this the old body node will be traversed and loops inside it may be
+ // transformed. This is fine, since the old body node will still be in the AST after
+ // the transformation that's queued here, and transforming loops inside it doesn't
+ // need to know the exact post-transform path to it.
+ }
+ }
+
+ mFoundLoopToChange = false;
+
+ // We traverse the body of the loop even if the loop is transformed.
+ if (node->getBody())
+ node->getBody()->traverse(this);
+
+ mLoop = prevLoop;
+}
+
+} // namespace
+
+bool SimplifyLoopConditions(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ SimplifyLoopConditionsTraverser traverser(nullptr, symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+bool SimplifyLoopConditions(TCompiler *compiler,
+ TIntermNode *root,
+ unsigned int conditionsToSimplifyMask,
+ TSymbolTable *symbolTable)
+{
+ IntermNodePatternMatcher conditionsToSimplify(conditionsToSimplifyMask);
+ SimplifyLoopConditionsTraverser traverser(&conditionsToSimplify, symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.h
new file mode 100644
index 0000000000..2a554c019d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SimplifyLoopConditions is an AST traverser that converts loop conditions and loop expressions
+// to regular statements inside the loop. This way further transformations that generate statements
+// from loop conditions and loop expressions work correctly.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_SIMPLIFYLOOPCONDITIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SIMPLIFYLOOPCONDITIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool SimplifyLoopConditions(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+[[nodiscard]] bool SimplifyLoopConditions(TCompiler *compiler,
+ TIntermNode *root,
+ unsigned int conditionsToSimplify,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_SIMPLIFYLOOPCONDITIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp
new file mode 100644
index 0000000000..45985954b0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp
@@ -0,0 +1,173 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SplitSequenceOperator is an AST traverser that detects sequence operator expressions that
+// go through further AST transformations that generate statements, and splits them so that
+// possible side effects of earlier parts of the sequence operator expression are guaranteed to be
+// evaluated before the latter parts of the sequence operator expression are evaluated.
+//
+
+#include "compiler/translator/tree_ops/SplitSequenceOperator.h"
+
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class SplitSequenceOperatorTraverser : public TLValueTrackingTraverser
+{
+ public:
+ SplitSequenceOperatorTraverser(unsigned int patternsToSplitMask, TSymbolTable *symbolTable);
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitTernary(Visit visit, TIntermTernary *node) override;
+
+ void nextIteration();
+ bool foundExpressionToSplit() const { return mFoundExpressionToSplit; }
+
+ protected:
+ // Marked to true once an operation that needs to be hoisted out of the expression has been
+ // found. After that, no more AST updates are performed on that traversal.
+ bool mFoundExpressionToSplit;
+ int mInsideSequenceOperator;
+
+ IntermNodePatternMatcher mPatternToSplitMatcher;
+};
+
+SplitSequenceOperatorTraverser::SplitSequenceOperatorTraverser(unsigned int patternsToSplitMask,
+ TSymbolTable *symbolTable)
+ : TLValueTrackingTraverser(true, false, true, symbolTable),
+ mFoundExpressionToSplit(false),
+ mInsideSequenceOperator(0),
+ mPatternToSplitMatcher(patternsToSplitMask)
+{}
+
+void SplitSequenceOperatorTraverser::nextIteration()
+{
+ mFoundExpressionToSplit = false;
+ mInsideSequenceOperator = 0;
+}
+
+bool SplitSequenceOperatorTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ if (mFoundExpressionToSplit)
+ return false;
+
+ if (mInsideSequenceOperator > 0 && visit == PreVisit)
+ {
+ // Detect expressions that need to be simplified
+ mFoundExpressionToSplit = mPatternToSplitMatcher.match(node, getParentNode());
+ return !mFoundExpressionToSplit;
+ }
+
+ return true;
+}
+
+bool SplitSequenceOperatorTraverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ if (mFoundExpressionToSplit)
+ return false;
+
+ if (mInsideSequenceOperator > 0 && visit == PreVisit)
+ {
+ // Detect expressions that need to be simplified
+ mFoundExpressionToSplit = mPatternToSplitMatcher.match(node);
+ return !mFoundExpressionToSplit;
+ }
+
+ return true;
+}
+
+bool SplitSequenceOperatorTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (node->getOp() == EOpComma)
+ {
+ if (visit == PreVisit)
+ {
+ if (mFoundExpressionToSplit)
+ {
+ return false;
+ }
+ mInsideSequenceOperator++;
+ }
+ else if (visit == PostVisit)
+ {
+ // Split sequence operators starting from the outermost one to preserve correct
+ // execution order.
+ if (mFoundExpressionToSplit && mInsideSequenceOperator == 1)
+ {
+ // Move the left side operand into a separate statement in the parent block.
+ TIntermSequence insertions;
+ insertions.push_back(node->getLeft());
+ insertStatementsInParentBlock(insertions);
+ // Replace the comma node with its right side operand.
+ queueReplacement(node->getRight(), OriginalNode::IS_DROPPED);
+ }
+ mInsideSequenceOperator--;
+ }
+ return true;
+ }
+
+ if (mFoundExpressionToSplit)
+ return false;
+
+ if (mInsideSequenceOperator > 0 && visit == PreVisit)
+ {
+ // Detect expressions that need to be simplified
+ mFoundExpressionToSplit =
+ mPatternToSplitMatcher.match(node, getParentNode(), isLValueRequiredHere());
+ return !mFoundExpressionToSplit;
+ }
+
+ return true;
+}
+
+bool SplitSequenceOperatorTraverser::visitTernary(Visit visit, TIntermTernary *node)
+{
+ if (mFoundExpressionToSplit)
+ return false;
+
+ if (mInsideSequenceOperator > 0 && visit == PreVisit)
+ {
+ // Detect expressions that need to be simplified
+ mFoundExpressionToSplit = mPatternToSplitMatcher.match(node);
+ return !mFoundExpressionToSplit;
+ }
+
+ return true;
+}
+
+} // namespace
+
+bool SplitSequenceOperator(TCompiler *compiler,
+ TIntermNode *root,
+ int patternsToSplitMask,
+ TSymbolTable *symbolTable)
+{
+ SplitSequenceOperatorTraverser traverser(patternsToSplitMask, symbolTable);
+ // Separate one expression at a time, and reset the traverser between iterations.
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.foundExpressionToSplit())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.foundExpressionToSplit());
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.h
new file mode 100644
index 0000000000..2a9f09a1f2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SplitSequenceOperator is an AST traverser that detects sequence operator expressions that
+// go through further AST transformations that generate statements, and splits them so that
+// possible side effects of earlier parts of the sequence operator expression are guaranteed to be
+// evaluated before the latter parts of the sequence operator expression are evaluated.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_SPLITSEQUENCEOPERATOR_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SPLITSEQUENCEOPERATOR_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool SplitSequenceOperator(TCompiler *compiler,
+ TIntermNode *root,
+ int patternsToSplitMask,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_SPLITSEQUENCEOPERATOR_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.cpp
new file mode 100644
index 0000000000..36e426f8e1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.cpp
@@ -0,0 +1,60 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// An AST traverser that rewrites for and while loops by replacing "condition" with
+// "condition && true" to work around condition bug on Intel Mac.
+class AddAndTrueToLoopConditionTraverser : public TIntermTraverser
+{
+ public:
+ AddAndTrueToLoopConditionTraverser() : TIntermTraverser(true, false, false) {}
+
+ bool visitLoop(Visit, TIntermLoop *loop) override
+ {
+ // do-while loop doesn't have this bug.
+ if (loop->getType() != ELoopFor && loop->getType() != ELoopWhile)
+ {
+ return true;
+ }
+
+ // For loop may not have a condition.
+ if (loop->getCondition() == nullptr)
+ {
+ return true;
+ }
+
+ // Constant true.
+ TIntermTyped *trueValue = CreateBoolNode(true);
+
+ // CONDITION && true.
+ TIntermBinary *andOp = new TIntermBinary(EOpLogicalAnd, loop->getCondition(), trueValue);
+ loop->setCondition(andOp);
+
+ return true;
+ }
+};
+
+} // anonymous namespace
+
+bool AddAndTrueToLoopCondition(TCompiler *compiler, TIntermNode *root)
+{
+ AddAndTrueToLoopConditionTraverser traverser;
+ root->traverse(&traverser);
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h
new file mode 100644
index 0000000000..d23158e81a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h
@@ -0,0 +1,31 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Rewrite condition in for and while loops to work around driver bug on Intel Mac.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_APPLE_ADDANDTRUETOLOOPCONDITION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_APPLE_ADDANDTRUETOLOOPCONDITION_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+#if defined(ANGLE_ENABLE_GLSL) && defined(ANGLE_ENABLE_APPLE_WORKAROUNDS)
+[[nodiscard]] bool AddAndTrueToLoopCondition(TCompiler *compiler, TIntermNode *root);
+#else
+[[nodiscard]] ANGLE_INLINE bool AddAndTrueToLoopCondition(TCompiler *compiler, TIntermNode *root)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_APPLE_ADDANDTRUETOLOOPCONDITION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.cpp
new file mode 100644
index 0000000000..de322aadab
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.cpp
@@ -0,0 +1,147 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RewriteDoWhile.cpp: rewrites do-while loops using another equivalent
+// construct.
+
+#include "compiler/translator/tree_ops/apple/RewriteDoWhile.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// An AST traverser that rewrites loops of the form
+// do {
+// CODE;
+// } while (CONDITION)
+//
+// to loops of the form
+// bool temp = false;
+// while (true) {
+// if (temp) {
+// if (!CONDITION) {
+// break;
+// }
+// }
+// temp = true;
+// CODE;
+// }
+//
+// The reason we don't use a simpler form, with for example just (temp && !CONDITION) in the
+// while condition, is that short-circuit is often badly supported by driver shader compiler.
+// The double if has the same effect, but forces shader compilers to behave.
+//
+// TODO(cwallez) when UnfoldShortCircuitIntoIf handles loops correctly, revisit this as we might
+// be able to use while (temp || CONDITION) with temp initially set to true then run
+// UnfoldShortCircuitIntoIf
+class DoWhileRewriter : public TIntermTraverser
+{
+ public:
+ DoWhileRewriter(TSymbolTable *symbolTable) : TIntermTraverser(true, false, false, symbolTable)
+ {}
+
+ bool visitBlock(Visit, TIntermBlock *node) override
+ {
+ // A well-formed AST can only have do-while inside TIntermBlock. By doing a prefix traversal
+ // we are able to replace the do-while in the sequence directly as the content of the
+ // do-while will be traversed later.
+
+ TIntermSequence *statements = node->getSequence();
+
+ // The statements vector will have new statements inserted when we encounter a do-while,
+ // which prevents us from using a range-based for loop. Using the usual i++ works, as
+ // the (two) new statements inserted replace the statement at the current position.
+ for (size_t i = 0; i < statements->size(); i++)
+ {
+ TIntermNode *statement = (*statements)[i];
+ TIntermLoop *loop = statement->getAsLoopNode();
+
+ if (loop == nullptr || loop->getType() != ELoopDoWhile)
+ {
+ continue;
+ }
+
+ // Found a loop to change.
+ const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
+ TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType);
+
+ // bool temp = false;
+ TIntermDeclaration *tempDeclaration =
+ CreateTempInitDeclarationNode(conditionVariable, CreateBoolNode(false));
+
+ // temp = true;
+ TIntermBinary *assignTrue =
+ CreateTempAssignmentNode(conditionVariable, CreateBoolNode(true));
+
+ // if (temp) {
+ // if (!CONDITION) {
+ // break;
+ // }
+ // }
+ TIntermIfElse *breakIf = nullptr;
+ {
+ TIntermBranch *breakStatement = new TIntermBranch(EOpBreak, nullptr);
+
+ TIntermBlock *breakBlock = new TIntermBlock();
+ breakBlock->getSequence()->push_back(breakStatement);
+
+ TIntermUnary *negatedCondition =
+ new TIntermUnary(EOpLogicalNot, loop->getCondition(), nullptr);
+
+ TIntermIfElse *innerIf = new TIntermIfElse(negatedCondition, breakBlock, nullptr);
+
+ TIntermBlock *innerIfBlock = new TIntermBlock();
+ innerIfBlock->getSequence()->push_back(innerIf);
+
+ breakIf = new TIntermIfElse(CreateTempSymbolNode(conditionVariable), innerIfBlock,
+ nullptr);
+ }
+
+ // Assemble the replacement loops, reusing the do-while loop's body and inserting our
+ // statements at the front.
+ TIntermLoop *newLoop = nullptr;
+ {
+ TIntermBlock *body = loop->getBody();
+ if (body == nullptr)
+ {
+ body = new TIntermBlock();
+ }
+ auto sequence = body->getSequence();
+ sequence->insert(sequence->begin(), assignTrue);
+ sequence->insert(sequence->begin(), breakIf);
+
+ newLoop = new TIntermLoop(ELoopWhile, nullptr, CreateBoolNode(true), nullptr, body);
+ }
+
+ TIntermSequence replacement;
+ replacement.push_back(tempDeclaration);
+ replacement.push_back(newLoop);
+
+ node->replaceChildNodeWithMultiple(loop, replacement);
+ }
+ return true;
+ }
+};
+
+} // anonymous namespace
+
+bool RewriteDoWhile(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ DoWhileRewriter rewriter(symbolTable);
+
+ root->traverse(&rewriter);
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.h
new file mode 100644
index 0000000000..71bdc8857b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RewriteDoWhile.h: rewrite do-while loops as while loops to work around
+// driver bugs
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEDOWHILE_H_
+#define COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEDOWHILE_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+#if defined(ANGLE_ENABLE_GLSL) && defined(ANGLE_ENABLE_APPLE_WORKAROUNDS)
+[[nodiscard]] bool RewriteDoWhile(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+#else
+[[nodiscard]] ANGLE_INLINE bool RewriteDoWhile(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEDOWHILE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.cpp
new file mode 100644
index 0000000000..49dc11efe2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.cpp
@@ -0,0 +1,1595 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteRowMajorMatrices: Rewrite row-major matrices as column-major.
+//
+
+#include "compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+// Only structs with matrices are tracked. If layout(row_major) is applied to a struct that doesn't
+// have matrices, it's silently dropped. This is also used to avoid creating duplicates for inner
+// structs that don't have matrices.
+struct StructConversionData
+{
+ // The converted struct with every matrix transposed.
+ TStructure *convertedStruct = nullptr;
+
+ // The copy-from and copy-to functions copying from a struct to its converted version and back.
+ TFunction *copyFromOriginal = nullptr;
+ TFunction *copyToOriginal = nullptr;
+};
+
+bool DoesFieldContainRowMajorMatrix(const TField *field, bool isBlockRowMajor)
+{
+ TLayoutMatrixPacking matrixPacking = field->type()->getLayoutQualifier().matrixPacking;
+
+ // The field is row major if either explicitly specified as such, or if it inherits it from the
+ // block layout qualifier.
+ if (matrixPacking == EmpColumnMajor || (matrixPacking == EmpUnspecified && !isBlockRowMajor))
+ {
+ return false;
+ }
+
+ // The field is qualified with row_major, but if it's not a matrix or a struct containing
+ // matrices, that's a useless qualifier.
+ const TType *type = field->type();
+ return type->isMatrix() || type->isStructureContainingMatrices();
+}
+
+TField *DuplicateField(const TField *field)
+{
+ return new TField(new TType(*field->type()), field->name(), field->line(), field->symbolType());
+}
+
+void SetColumnMajor(TType *type)
+{
+ TLayoutQualifier layoutQualifier = type->getLayoutQualifier();
+ layoutQualifier.matrixPacking = EmpColumnMajor;
+ type->setLayoutQualifier(layoutQualifier);
+}
+
+TType *TransposeMatrixType(const TType *type)
+{
+ TType *newType = new TType(*type);
+
+ SetColumnMajor(newType);
+
+ newType->setPrimarySize(type->getRows());
+ newType->setSecondarySize(type->getCols());
+
+ return newType;
+}
+
+void CopyArraySizes(const TType *from, TType *to)
+{
+ if (from->isArray())
+ {
+ to->makeArrays(from->getArraySizes());
+ }
+}
+
+// Determine if the node is an index node (array index or struct field selection). For the purposes
+// of this transformation, swizzle nodes are considered index nodes too.
+bool IsIndexNode(TIntermNode *node, TIntermNode *child)
+{
+ if (node->getAsSwizzleNode())
+ {
+ return true;
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode == nullptr || child != binaryNode->getLeft())
+ {
+ return false;
+ }
+
+ TOperator op = binaryNode->getOp();
+
+ return op == EOpIndexDirect || op == EOpIndexDirectInterfaceBlock ||
+ op == EOpIndexDirectStruct || op == EOpIndexIndirect;
+}
+
+TIntermSymbol *CopyToTempVariable(TSymbolTable *symbolTable,
+ TIntermTyped *node,
+ TIntermSequence *prependStatements)
+{
+ TVariable *temp = CreateTempVariable(symbolTable, &node->getType());
+ TIntermDeclaration *tempDecl = CreateTempInitDeclarationNode(temp, node);
+ prependStatements->push_back(tempDecl);
+
+ return new TIntermSymbol(temp);
+}
+
+TIntermAggregate *CreateStructCopyCall(const TFunction *copyFunc, TIntermTyped *expression)
+{
+ TIntermSequence args = {expression};
+ return TIntermAggregate::CreateFunctionCall(*copyFunc, &args);
+}
+
+TIntermTyped *CreateTransposeCall(TSymbolTable *symbolTable, TIntermTyped *expression)
+{
+ TIntermSequence args = {expression};
+ return CreateBuiltInFunctionCallNode("transpose", &args, *symbolTable, 300);
+}
+
+TOperator GetIndex(TSymbolTable *symbolTable,
+ TIntermNode *node,
+ TIntermSequence *indices,
+ TIntermSequence *prependStatements)
+{
+ // Swizzle nodes are converted EOpIndexDirect for simplicity, with one index per swizzle
+ // channel.
+ TIntermSwizzle *asSwizzle = node->getAsSwizzleNode();
+ if (asSwizzle)
+ {
+ for (int channel : asSwizzle->getSwizzleOffsets())
+ {
+ indices->push_back(CreateIndexNode(channel));
+ }
+ return EOpIndexDirect;
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ ASSERT(binaryNode);
+
+ TOperator op = binaryNode->getOp();
+ ASSERT(op == EOpIndexDirect || op == EOpIndexDirectInterfaceBlock ||
+ op == EOpIndexDirectStruct || op == EOpIndexIndirect);
+
+ TIntermTyped *rhs = binaryNode->getRight()->deepCopy();
+ if (rhs->getAsConstantUnion() == nullptr)
+ {
+ rhs = CopyToTempVariable(symbolTable, rhs, prependStatements);
+ }
+
+ indices->push_back(rhs);
+ return op;
+}
+
+TIntermTyped *ReplicateIndexNode(TSymbolTable *symbolTable,
+ TIntermNode *node,
+ TIntermTyped *lhs,
+ TIntermSequence *indices)
+{
+ TIntermSwizzle *asSwizzle = node->getAsSwizzleNode();
+ if (asSwizzle)
+ {
+ return new TIntermSwizzle(lhs, asSwizzle->getSwizzleOffsets());
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ ASSERT(binaryNode);
+
+ ASSERT(indices->size() == 1);
+ TIntermTyped *rhs = indices->front()->getAsTyped();
+
+ return new TIntermBinary(binaryNode->getOp(), lhs, rhs);
+}
+
+TOperator GetIndexOp(TIntermNode *node)
+{
+ return node->getAsConstantUnion() ? EOpIndexDirect : EOpIndexIndirect;
+}
+
+bool IsConvertedField(TIntermTyped *indexNode,
+ const angle::HashMap<const TField *, bool> &convertedFields)
+{
+ TIntermBinary *asBinary = indexNode->getAsBinaryNode();
+ if (asBinary == nullptr)
+ {
+ return false;
+ }
+
+ if (asBinary->getOp() != EOpIndexDirectInterfaceBlock)
+ {
+ return false;
+ }
+
+ const TInterfaceBlock *interfaceBlock = asBinary->getLeft()->getType().getInterfaceBlock();
+ ASSERT(interfaceBlock);
+
+ TIntermConstantUnion *fieldIndexNode = asBinary->getRight()->getAsConstantUnion();
+ ASSERT(fieldIndexNode);
+ ASSERT(fieldIndexNode->getConstantValue() != nullptr);
+
+ int fieldIndex = fieldIndexNode->getConstantValue()->getIConst();
+ const TField *field = interfaceBlock->fields()[fieldIndex];
+
+ return convertedFields.count(field) > 0 && convertedFields.at(field);
+}
+
+// A helper class to transform expressions of array type. Iterates over every element of the
+// array.
+class TransformArrayHelper
+{
+ public:
+ TransformArrayHelper(TIntermTyped *baseExpression)
+ : mBaseExpression(baseExpression),
+ mBaseExpressionType(baseExpression->getType()),
+ mArrayIndices(mBaseExpressionType.getArraySizes().size(), 0)
+ {}
+
+ TIntermTyped *getNextElement(TIntermTyped *valueExpression, TIntermTyped **valueElementOut)
+ {
+ const TSpan<const unsigned int> &arraySizes = mBaseExpressionType.getArraySizes();
+
+ // If the last index overflows, element enumeration is done.
+ if (mArrayIndices.back() >= arraySizes.back())
+ {
+ return nullptr;
+ }
+
+ TIntermTyped *element = getCurrentElement(mBaseExpression);
+ if (valueExpression)
+ {
+ *valueElementOut = getCurrentElement(valueExpression);
+ }
+
+ incrementIndices(arraySizes);
+ return element;
+ }
+
+ void accumulateForRead(TSymbolTable *symbolTable,
+ TIntermTyped *transformedElement,
+ TIntermSequence *prependStatements)
+ {
+ TIntermTyped *temp = CopyToTempVariable(symbolTable, transformedElement, prependStatements);
+ mReadTransformConstructorArgs.push_back(temp);
+ }
+
+ TIntermTyped *constructReadTransformExpression()
+ {
+ const TSpan<const unsigned int> &baseTypeArraySizes = mBaseExpressionType.getArraySizes();
+ TVector<unsigned int> arraySizes(baseTypeArraySizes.begin(), baseTypeArraySizes.end());
+ TIntermTyped *firstElement = mReadTransformConstructorArgs.front()->getAsTyped();
+ const TType &baseType = firstElement->getType();
+
+ // If N dimensions, acc[0] == size[0] and acc[i] == size[i] * acc[i-1].
+ // The last value is unused, and is not present.
+ TVector<unsigned int> accumulatedArraySizes(arraySizes.size() - 1);
+
+ if (accumulatedArraySizes.size() > 0)
+ {
+ accumulatedArraySizes[0] = arraySizes[0];
+ }
+ for (size_t index = 1; index + 1 < arraySizes.size(); ++index)
+ {
+ accumulatedArraySizes[index] = accumulatedArraySizes[index - 1] * arraySizes[index];
+ }
+
+ return constructReadTransformExpressionHelper(arraySizes, accumulatedArraySizes, baseType,
+ 0);
+ }
+
+ private:
+ TIntermTyped *getCurrentElement(TIntermTyped *expression)
+ {
+ TIntermTyped *element = expression->deepCopy();
+ for (auto it = mArrayIndices.rbegin(); it != mArrayIndices.rend(); ++it)
+ {
+ unsigned int index = *it;
+ element = new TIntermBinary(EOpIndexDirect, element, CreateIndexNode(index));
+ }
+ return element;
+ }
+
+ void incrementIndices(const TSpan<const unsigned int> &arraySizes)
+ {
+ // Assume mArrayIndices is an N digit number, where digit i is in the range
+ // [0, arraySizes[i]). This function increments this number. Last digit is the most
+ // significant digit.
+ for (size_t digitIndex = 0; digitIndex < arraySizes.size(); ++digitIndex)
+ {
+ ++mArrayIndices[digitIndex];
+ if (mArrayIndices[digitIndex] < arraySizes[digitIndex])
+ {
+ break;
+ }
+ if (digitIndex + 1 != arraySizes.size())
+ {
+ // This digit has now overflown and is reset to 0, carry will be added to the next
+ // digit. The most significant digit will keep the overflow though, to make it
+ // clear we have exhausted the range.
+ mArrayIndices[digitIndex] = 0;
+ }
+ }
+ }
+
+ TIntermTyped *constructReadTransformExpressionHelper(
+ const TVector<unsigned int> &arraySizes,
+ const TVector<unsigned int> &accumulatedArraySizes,
+ const TType &baseType,
+ size_t elementsOffset)
+ {
+ ASSERT(!arraySizes.empty());
+
+ TType *transformedType = new TType(baseType);
+ transformedType->makeArrays(arraySizes);
+
+ // If one dimensional, create the constructor with the given elements.
+ if (arraySizes.size() == 1)
+ {
+ ASSERT(accumulatedArraySizes.size() == 0);
+
+ auto sliceStart = mReadTransformConstructorArgs.begin() + elementsOffset;
+ TIntermSequence slice(sliceStart, sliceStart + arraySizes[0]);
+
+ return TIntermAggregate::CreateConstructor(*transformedType, &slice);
+ }
+
+ // If not, create constructors for every column recursively.
+ TVector<unsigned int> subArraySizes(arraySizes.begin(), arraySizes.end() - 1);
+ TVector<unsigned int> subArrayAccumulatedSizes(accumulatedArraySizes.begin(),
+ accumulatedArraySizes.end() - 1);
+
+ TIntermSequence constructorArgs;
+ unsigned int colStride = accumulatedArraySizes.back();
+ for (size_t col = 0; col < arraySizes.back(); ++col)
+ {
+ size_t colElementsOffset = elementsOffset + col * colStride;
+
+ constructorArgs.push_back(constructReadTransformExpressionHelper(
+ subArraySizes, subArrayAccumulatedSizes, baseType, colElementsOffset));
+ }
+
+ return TIntermAggregate::CreateConstructor(*transformedType, &constructorArgs);
+ }
+
+ TIntermTyped *mBaseExpression;
+ const TType &mBaseExpressionType;
+ TVector<unsigned int> mArrayIndices;
+
+ TIntermSequence mReadTransformConstructorArgs;
+};
+
+// Traverser that:
+//
+// 1. Converts |layout(row_major) matCxR M| to |layout(column_major) matRxC Mt|.
+// 2. Converts |layout(row_major) S s| to |layout(column_major) St st|, where S is a struct that
+// contains matrices, and St is a new struct with the transformation in 1 applied to matrix
+// members (recursively).
+// 3. When read from, the following transformations are applied:
+//
+// M -> transpose(Mt)
+// M[c] -> gvecN(Mt[0][c], Mt[1][c], ..., Mt[N-1][c])
+// M[c][r] -> Mt[r][c]
+// M[c].yz -> gvec2(Mt[1][c], Mt[2][c])
+// MArr -> MType[D1]..[DN](transpose(MtArr[0]...[0]), ...)
+// s -> copy_St_to_S(st)
+// sArr -> SType[D1]...[DN](copy_St_to_S(stArr[0]..[0]), ...)
+// (matrix reads through struct are transformed similarly to M)
+//
+// 4. When written to, the following transformations are applied:
+//
+// M = exp -> Mt = transpose(exp)
+// M[c] = exp -> temp = exp
+// Mt[0][c] = temp[0]
+// Mt[1][c] = temp[1]
+// ...
+// Mt[N-1][c] = temp[N-1]
+// M[c][r] = exp -> Mt[r][c] = exp
+// M[c].yz = exp -> temp = exp
+// Mt[1][c] = temp[0]
+// Mt[2][c] = temp[1]
+// MArr = exp -> temp = exp
+// Mt = MtType[D1]..[DN](temp([0]...[0]), ...)
+// s = exp -> st = copy_S_to_St(exp)
+// sArr = exp -> temp = exp
+// St = StType[D1]...[DN](copy_S_to_St(temp[0]..[0]), ...)
+// (matrix writes through struct are transformed similarly to M)
+//
+// 5. If any of the above is passed to an `inout` parameter, both transformations are applied:
+//
+// f(M[c]) -> temp = gvecN(Mt[0][c], Mt[1][c], ..., Mt[N-1][c])
+// f(temp)
+// Mt[0][c] = temp[0]
+// Mt[1][c] = temp[1]
+// ...
+// Mt[N-1][c] = temp[N-1]
+//
+// f(s) -> temp = copy_St_to_S(st)
+// f(temp)
+// st = copy_S_to_St(temp)
+//
+// If passed to an `out` parameter, the `temp` parameter is simply not initialized.
+//
+// 6. If the expression leading to the matrix or struct has array subscripts, temp values are
+// created for them to avoid duplicating side effects.
+//
+class RewriteRowMajorMatricesTraverser : public TIntermTraverser
+{
+ public:
+ RewriteRowMajorMatricesTraverser(TCompiler *compiler, TSymbolTable *symbolTable)
+ : TIntermTraverser(true, true, true, symbolTable),
+ mCompiler(compiler),
+ mStructMapOut(&mOuterPass.structMap),
+ mInterfaceBlockMap(&mOuterPass.interfaceBlockMap),
+ mInterfaceBlockFieldConvertedIn(mOuterPass.interfaceBlockFieldConverted),
+ mCopyFunctionDefinitionsOut(&mOuterPass.copyFunctionDefinitions),
+ mOuterTraverser(nullptr),
+ mInnerPassRoot(nullptr),
+ mIsProcessingInnerPassSubtree(false)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ // No need to process declarations in inner passes.
+ if (mInnerPassRoot != nullptr)
+ {
+ return true;
+ }
+
+ if (visit != PreVisit)
+ {
+ return true;
+ }
+
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+
+ // If it's a struct declaration that has matrices, remember it. If a row-major instance
+ // of it is created, it will have to be converted.
+ if (type.isStructSpecifier() && type.isStructureContainingMatrices())
+ {
+ const TStructure *structure = type.getStruct();
+ ASSERT(structure);
+
+ ASSERT(mOuterPass.structMap.count(structure) == 0);
+
+ StructConversionData structData;
+ mOuterPass.structMap[structure] = structData;
+
+ return false;
+ }
+
+ // If it's an interface block, it may have to be converted if it contains any row-major
+ // fields.
+ if (type.isInterfaceBlock() && type.getInterfaceBlock()->containsMatrices())
+ {
+ const TInterfaceBlock *block = type.getInterfaceBlock();
+ ASSERT(block);
+ bool isBlockRowMajor = type.getLayoutQualifier().matrixPacking == EmpRowMajor;
+
+ const TFieldList &fields = block->fields();
+ bool anyRowMajor = isBlockRowMajor;
+
+ for (const TField *field : fields)
+ {
+ if (DoesFieldContainRowMajorMatrix(field, isBlockRowMajor))
+ {
+ anyRowMajor = true;
+ break;
+ }
+ }
+
+ if (anyRowMajor)
+ {
+ convertInterfaceBlock(node);
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ // If in inner pass, only process if the symbol is under that root.
+ if (mInnerPassRoot != nullptr && !mIsProcessingInnerPassSubtree)
+ {
+ return;
+ }
+
+ const TVariable *variable = &symbol->variable();
+ bool needsRewrite = mInterfaceBlockMap->count(variable) != 0;
+
+ // If it's a field of a nameless interface block, it may still need conversion.
+ if (!needsRewrite)
+ {
+ // Nameless interface block field symbols have the interface block pointer set, but are
+ // not interface blocks.
+ if (symbol->getType().getInterfaceBlock() && !variable->getType().isInterfaceBlock())
+ {
+ needsRewrite = convertNamelessInterfaceBlockField(symbol);
+ }
+ }
+
+ if (needsRewrite)
+ {
+ transformExpression(symbol);
+ }
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ if (node == mInnerPassRoot)
+ {
+ // We only want to process the right-hand side of an assignment in inner passes. When
+ // visit is InVisit, the left-hand side is already processed, and the right-hand side is
+ // next. Set a flag to mark this duration.
+ mIsProcessingInnerPassSubtree = visit == InVisit;
+ }
+
+ return true;
+ }
+
+ TIntermSequence *getStructCopyFunctions() { return &mOuterPass.copyFunctionDefinitions; }
+
+ private:
+ typedef angle::HashMap<const TStructure *, StructConversionData> StructMap;
+ typedef angle::HashMap<const TVariable *, TVariable *> InterfaceBlockMap;
+ typedef angle::HashMap<const TField *, bool> InterfaceBlockFieldConverted;
+
+ RewriteRowMajorMatricesTraverser(
+ TSymbolTable *symbolTable,
+ RewriteRowMajorMatricesTraverser *outerTraverser,
+ InterfaceBlockMap *interfaceBlockMap,
+ const InterfaceBlockFieldConverted &interfaceBlockFieldConverted,
+ StructMap *structMap,
+ TIntermSequence *copyFunctionDefinitions,
+ TIntermBinary *innerPassRoot)
+ : TIntermTraverser(true, true, true, symbolTable),
+ mStructMapOut(structMap),
+ mInterfaceBlockMap(interfaceBlockMap),
+ mInterfaceBlockFieldConvertedIn(interfaceBlockFieldConverted),
+ mCopyFunctionDefinitionsOut(copyFunctionDefinitions),
+ mOuterTraverser(outerTraverser),
+ mInnerPassRoot(innerPassRoot),
+ mIsProcessingInnerPassSubtree(false)
+ {}
+
+ void convertInterfaceBlock(TIntermDeclaration *node)
+ {
+ ASSERT(mInnerPassRoot == nullptr);
+
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ TIntermTyped *variableNode = sequence.front()->getAsTyped();
+ const TType &type = variableNode->getType();
+ const TInterfaceBlock *block = type.getInterfaceBlock();
+ ASSERT(block);
+
+ bool isBlockRowMajor = type.getLayoutQualifier().matrixPacking == EmpRowMajor;
+
+ // Recreate the struct with its row-major fields converted to column-major equivalents.
+ TIntermSequence newDeclarations;
+
+ TFieldList *newFields = new TFieldList;
+ for (const TField *field : block->fields())
+ {
+ TField *newField = nullptr;
+
+ if (DoesFieldContainRowMajorMatrix(field, isBlockRowMajor))
+ {
+ newField = convertField(field, &newDeclarations);
+
+ // Remember that this field was converted.
+ mOuterPass.interfaceBlockFieldConverted[field] = true;
+ }
+ else
+ {
+ newField = DuplicateField(field);
+ }
+
+ newFields->push_back(newField);
+ }
+
+ // Create a new interface block with these fields.
+ TLayoutQualifier blockLayoutQualifier = type.getLayoutQualifier();
+ blockLayoutQualifier.matrixPacking = EmpColumnMajor;
+
+ TInterfaceBlock *newInterfaceBlock =
+ new TInterfaceBlock(mSymbolTable, block->name(), newFields, blockLayoutQualifier,
+ block->symbolType(), block->extensions());
+
+ // Create a new declaration with the new type. Declarations are separated at this point,
+ // so there should be only one variable here.
+ ASSERT(sequence.size() == 1);
+
+ TType *newInterfaceBlockType =
+ new TType(newInterfaceBlock, type.getQualifier(), blockLayoutQualifier);
+
+ TIntermDeclaration *newDeclaration = new TIntermDeclaration;
+ const TVariable *variable = &variableNode->getAsSymbolNode()->variable();
+
+ const TType *newType = newInterfaceBlockType;
+ if (type.isArray())
+ {
+ TType *newArrayType = new TType(*newType);
+ CopyArraySizes(&type, newArrayType);
+ newType = newArrayType;
+ }
+
+ // If the interface block variable itself is temp, use an empty name.
+ bool variableIsTemp = variable->symbolType() == SymbolType::Empty;
+ const ImmutableString &variableName =
+ variableIsTemp ? kEmptyImmutableString : variable->name();
+
+ TVariable *newVariable = new TVariable(mSymbolTable, variableName, newType,
+ variable->symbolType(), variable->extensions());
+
+ newDeclaration->appendDeclarator(new TIntermSymbol(newVariable));
+
+ mOuterPass.interfaceBlockMap[variable] = newVariable;
+
+ newDeclarations.push_back(newDeclaration);
+
+ // Replace the interface block definition with the new one, prepending any new struct
+ // definitions.
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(newDeclarations));
+ }
+
+ bool convertNamelessInterfaceBlockField(TIntermSymbol *symbol)
+ {
+ const TVariable *variable = &symbol->variable();
+ const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
+
+ // Find the variable corresponding to this interface block. If the interface block
+ // is not rewritten, or this refers to a field that is not rewritten, there's
+ // nothing to do.
+ for (auto iter : *mInterfaceBlockMap)
+ {
+ // Skip other rewritten nameless interface block fields.
+ if (!iter.first->getType().isInterfaceBlock())
+ {
+ continue;
+ }
+
+ // Skip if this is not a field of this rewritten interface block.
+ if (iter.first->getType().getInterfaceBlock() != interfaceBlock)
+ {
+ continue;
+ }
+
+ const ImmutableString symbolName = symbol->getName();
+
+ // Find which field it is
+ const TVector<TField *> fields = interfaceBlock->fields();
+ const size_t fieldIndex = variable->getType().getInterfaceBlockFieldIndex();
+ ASSERT(fieldIndex < fields.size());
+
+ const TField *field = fields[fieldIndex];
+ ASSERT(field->name() == symbolName);
+
+ // If this field doesn't need a rewrite, there's nothing to do.
+ if (mInterfaceBlockFieldConvertedIn.count(field) == 0 ||
+ !mInterfaceBlockFieldConvertedIn.at(field))
+ {
+ break;
+ }
+
+ // Create a new variable that references the replaced interface block.
+ TType *newType = new TType(variable->getType());
+ newType->setInterfaceBlockField(iter.second->getType().getInterfaceBlock(), fieldIndex);
+
+ TVariable *newVariable = new TVariable(mSymbolTable, variable->name(), newType,
+ variable->symbolType(), variable->extensions());
+
+ (*mInterfaceBlockMap)[variable] = newVariable;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ void convertStruct(const TStructure *structure, TIntermSequence *newDeclarations)
+ {
+ ASSERT(mInnerPassRoot == nullptr);
+
+ ASSERT(mOuterPass.structMap.count(structure) != 0);
+ StructConversionData *structData = &mOuterPass.structMap[structure];
+
+ if (structData->convertedStruct)
+ {
+ return;
+ }
+
+ TFieldList *newFields = new TFieldList;
+ for (const TField *field : structure->fields())
+ {
+ newFields->push_back(convertField(field, newDeclarations));
+ }
+
+ // Create unique names for the converted structs. We can't leave them nameless and have
+ // a name autogenerated similar to temp variables, as nameless structs exist. A fake
+ // variable is created for the sole purpose of generating a temp name.
+ TVariable *newStructTypeName =
+ new TVariable(mSymbolTable, kEmptyImmutableString,
+ StaticType::GetBasic<EbtUInt, EbpUndefined>(), SymbolType::Empty);
+
+ TStructure *newStruct = new TStructure(mSymbolTable, newStructTypeName->name(), newFields,
+ SymbolType::AngleInternal);
+ TType *newType = new TType(newStruct, true);
+ TVariable *newStructVar =
+ new TVariable(mSymbolTable, kEmptyImmutableString, newType, SymbolType::Empty);
+
+ TIntermDeclaration *structDecl = new TIntermDeclaration;
+ structDecl->appendDeclarator(new TIntermSymbol(newStructVar));
+
+ newDeclarations->push_back(structDecl);
+
+ structData->convertedStruct = newStruct;
+ }
+
+ TField *convertField(const TField *field, TIntermSequence *newDeclarations)
+ {
+ ASSERT(mInnerPassRoot == nullptr);
+
+ TField *newField = nullptr;
+
+ const TType *fieldType = field->type();
+ TType *newType = nullptr;
+
+ if (fieldType->isStructureContainingMatrices())
+ {
+ // If the field is a struct instance, convert the struct and replace the field
+ // with an instance of the new struct.
+ const TStructure *fieldTypeStruct = fieldType->getStruct();
+ convertStruct(fieldTypeStruct, newDeclarations);
+
+ StructConversionData &structData = mOuterPass.structMap[fieldTypeStruct];
+ newType = new TType(structData.convertedStruct, false);
+ SetColumnMajor(newType);
+ CopyArraySizes(fieldType, newType);
+ }
+ else if (fieldType->isMatrix())
+ {
+ // If the field is a matrix, transpose the matrix and replace the field with
+ // that, removing the matrix packing qualifier.
+ newType = TransposeMatrixType(fieldType);
+ }
+
+ if (newType)
+ {
+ newField = new TField(newType, field->name(), field->line(), field->symbolType());
+ }
+ else
+ {
+ newField = DuplicateField(field);
+ }
+
+ return newField;
+ }
+
+ void determineAccess(TIntermNode *expression,
+ TIntermNode *accessor,
+ bool *isReadOut,
+ bool *isWriteOut)
+ {
+ // If passing to a function, look at whether the parameter is in, out or inout.
+ TIntermAggregate *functionCall = accessor->getAsAggregate();
+
+ if (functionCall)
+ {
+ TIntermSequence *arguments = functionCall->getSequence();
+ for (size_t argIndex = 0; argIndex < arguments->size(); ++argIndex)
+ {
+ if ((*arguments)[argIndex] == expression)
+ {
+ TQualifier qualifier = EvqParamIn;
+
+ // If the aggregate is not a function call, it's a constructor, and so every
+ // argument is an input.
+ const TFunction *function = functionCall->getFunction();
+ if (function)
+ {
+ const TVariable *param = function->getParam(argIndex);
+ qualifier = param->getType().getQualifier();
+ }
+
+ *isReadOut = qualifier != EvqParamOut;
+ *isWriteOut = qualifier == EvqParamOut || qualifier == EvqParamInOut;
+ break;
+ }
+ }
+ return;
+ }
+
+ TIntermBinary *assignment = accessor->getAsBinaryNode();
+ if (assignment && IsAssignment(assignment->getOp()))
+ {
+ // If expression is on the right of assignment, it's being read from.
+ *isReadOut = assignment->getRight() == expression;
+ // If it's on the left of assignment, it's being written to.
+ *isWriteOut = assignment->getLeft() == expression;
+ return;
+ }
+
+ // Any other usage is a read.
+ *isReadOut = true;
+ *isWriteOut = false;
+ }
+
+ void transformExpression(TIntermSymbol *symbol)
+ {
+ // Walk up the parent chain while the nodes are EOpIndex* (whether array indexing or struct
+ // field selection) or swizzle and construct the replacement expression. This traversal can
+ // lead to one of the following possibilities:
+ //
+ // - a.b[N].etc.s (struct, or struct array): copy function should be declared and used,
+ // - a.b[N].etc.M (matrix or matrix array): transpose() should be used,
+ // - a.b[N].etc.M[c] (a column): each element in column needs to be handled separately,
+ // - a.b[N].etc.M[c].yz (multiple elements): similar to whole column, but a subset of
+ // elements,
+ // - a.b[N].etc.M[c][r] (an element): single element to handle.
+ // - a.b[N].etc.x (not struct or matrix): not modified
+ //
+ // primaryIndex will contain c, if any. secondaryIndices will contain {0, ..., R-1}
+ // (if no [r] or swizzle), {r} (if [r]), or {1, 2} (corresponding to .yz) if any.
+ //
+ // In all cases, the base symbol is replaced. |baseExpression| will contain everything up
+ // to (and not including) the last index/swizzle operations, i.e. a.b[N].etc.s/M/x. Any
+ // non constant array subscript is assigned to a temp variable to avoid duplicating side
+ // effects.
+ //
+ // ---
+ //
+ // NOTE that due to the use of insertStatementsInParentBlock, cases like this will be
+ // mistranslated, and this bug is likely present in most transformations that use this
+ // feature:
+ //
+ // if (x == 1 && a.b[x = 2].etc.M = value)
+ //
+ // which will translate to:
+ //
+ // temp = (x = 2)
+ // if (x == 1 && a.b[temp].etc.M = transpose(value))
+ //
+ // See http://anglebug.com/3829.
+ //
+ TIntermTyped *baseExpression =
+ new TIntermSymbol(mInterfaceBlockMap->at(&symbol->variable()));
+ const TStructure *structure = nullptr;
+
+ TIntermNode *primaryIndex = nullptr;
+ TIntermSequence secondaryIndices;
+
+ // In some cases, it is necessary to prepend or append statements. Those are captured in
+ // |prependStatements| and |appendStatements|.
+ TIntermSequence prependStatements;
+ TIntermSequence appendStatements;
+
+ // If the expression is neither a struct or matrix, no modification is necessary.
+ // If it's a struct that doesn't have matrices, again there's no transformation necessary.
+ // If it's an interface block matrix field that didn't need to be transposed, no
+ // transpformation is necessary.
+ //
+ // In all these cases, |baseExpression| contains all of the original expression.
+ //
+ // If the starting symbol itself is a field of a nameless interface block, it needs
+ // conversion if we reach here.
+ bool requiresTransformation = !symbol->getType().isInterfaceBlock();
+
+ uint32_t accessorIndex = 0;
+ TIntermTyped *previousAncestor = symbol;
+ while (IsIndexNode(getAncestorNode(accessorIndex), previousAncestor))
+ {
+ TIntermTyped *ancestor = getAncestorNode(accessorIndex)->getAsTyped();
+ ASSERT(ancestor);
+
+ const TType &previousAncestorType = previousAncestor->getType();
+
+ TIntermSequence indices;
+ TOperator op = GetIndex(mSymbolTable, ancestor, &indices, &prependStatements);
+
+ bool opIsIndex = op == EOpIndexDirect || op == EOpIndexIndirect;
+ bool isArrayIndex = opIsIndex && previousAncestorType.isArray();
+ bool isMatrixIndex = opIsIndex && previousAncestorType.isMatrix();
+
+ // If it's a direct index in a matrix, it's the primary index.
+ bool isMatrixPrimarySubscript = isMatrixIndex && !isArrayIndex;
+ ASSERT(!isMatrixPrimarySubscript ||
+ (primaryIndex == nullptr && secondaryIndices.empty()));
+ // If primary index is seen and the ancestor is still an index, it must be a direct
+ // index as the secondary one. Note that if primaryIndex is set, there can only ever be
+ // one more parent of interest, and that's subscripting the second dimension.
+ bool isMatrixSecondarySubscript = primaryIndex != nullptr;
+ ASSERT(!isMatrixSecondarySubscript || (opIsIndex && !isArrayIndex));
+
+ if (requiresTransformation && isMatrixPrimarySubscript)
+ {
+ ASSERT(indices.size() == 1);
+ primaryIndex = indices.front();
+
+ // Default the secondary indices to include every row. If there's a secondary
+ // subscript provided, it will override this.
+ const uint8_t rows = previousAncestorType.getRows();
+ for (uint8_t r = 0; r < rows; ++r)
+ {
+ secondaryIndices.push_back(CreateIndexNode(r));
+ }
+ }
+ else if (isMatrixSecondarySubscript)
+ {
+ ASSERT(requiresTransformation);
+
+ secondaryIndices = indices;
+
+ // Indices after this point are not interesting. There can't actually be any other
+ // index nodes other than desktop GLSL's swizzles on scalars, like M[1][2].yyy.
+ ++accessorIndex;
+ break;
+ }
+ else
+ {
+ // Replicate the expression otherwise.
+ baseExpression =
+ ReplicateIndexNode(mSymbolTable, ancestor, baseExpression, &indices);
+
+ const TType &ancestorType = ancestor->getType();
+ structure = ancestorType.getStruct();
+
+ requiresTransformation =
+ requiresTransformation ||
+ IsConvertedField(ancestor, mInterfaceBlockFieldConvertedIn);
+
+ // If we reach a point where the expression is neither a matrix-containing struct
+ // nor a matrix, there's no transformation required. This can happen if we decend
+ // through a struct marked with row-major but arrive at a member that doesn't
+ // include a matrix.
+ if (!ancestorType.isMatrix() && !ancestorType.isStructureContainingMatrices())
+ {
+ requiresTransformation = false;
+ }
+ }
+
+ previousAncestor = ancestor;
+ ++accessorIndex;
+ }
+
+ TIntermNode *originalExpression =
+ accessorIndex == 0 ? symbol : getAncestorNode(accessorIndex - 1);
+ TIntermNode *accessor = getAncestorNode(accessorIndex);
+
+ // if accessor is EOpArrayLength, we don't need to perform any transformations either.
+ // Note that this only applies to unsized arrays, as the RemoveArrayLengthMethod()
+ // transformation would have removed this operation otherwise.
+ TIntermUnary *accessorAsUnary = accessor->getAsUnaryNode();
+ if (requiresTransformation && accessorAsUnary && accessorAsUnary->getOp() == EOpArrayLength)
+ {
+ ASSERT(accessorAsUnary->getOperand() == originalExpression);
+ ASSERT(accessorAsUnary->getOperand()->getType().isUnsizedArray());
+
+ requiresTransformation = false;
+
+ // We need to replace the whole expression including the EOpArrayLength, to avoid
+ // confusing the replacement code as the original and new expressions don't have the
+ // same type (one is the transpose of the other). This doesn't affect the .length()
+ // operation, so this replacement is ok, though it's not worth special-casing this in
+ // the node replacement algorithm.
+ //
+ // Note: the |if (!requiresTransformation)| immediately below will be entered after
+ // this.
+ originalExpression = accessor;
+ accessor = getAncestorNode(accessorIndex + 1);
+ baseExpression = new TIntermUnary(EOpArrayLength, baseExpression, nullptr);
+ }
+
+ if (!requiresTransformation)
+ {
+ ASSERT(primaryIndex == nullptr);
+ queueReplacementWithParent(accessor, originalExpression, baseExpression,
+ OriginalNode::IS_DROPPED);
+
+ RewriteRowMajorMatricesTraverser *traverser = mOuterTraverser ? mOuterTraverser : this;
+ traverser->insertStatementsInParentBlock(prependStatements, appendStatements);
+ return;
+ }
+
+ ASSERT(structure == nullptr || primaryIndex == nullptr);
+ ASSERT(structure != nullptr || baseExpression->getType().isMatrix());
+
+ // At the end, we can determine if the expression is being read from or written to (or both,
+ // if sent as an inout parameter to a function). For the sake of the transformation, the
+ // left-hand side of operations like += can be treated as "written to", without necessarily
+ // "read from".
+ bool isRead = false;
+ bool isWrite = false;
+
+ determineAccess(originalExpression, accessor, &isRead, &isWrite);
+
+ ASSERT(isRead || isWrite);
+
+ TIntermTyped *readExpression = nullptr;
+ if (isRead)
+ {
+ readExpression = transformReadExpression(
+ baseExpression, primaryIndex, &secondaryIndices, structure, &prependStatements);
+
+ // If both read from and written to (i.e. passed to inout parameter), store the
+ // expression in a temp variable and pass that to the function.
+ if (isWrite)
+ {
+ readExpression =
+ CopyToTempVariable(mSymbolTable, readExpression, &prependStatements);
+ }
+
+ // Replace the original expression with the transformed one. Read transformations
+ // always generate a single expression that can be used in place of the original (as
+ // oppposed to write transformations that can generate multiple statements).
+ queueReplacementWithParent(accessor, originalExpression, readExpression,
+ OriginalNode::IS_DROPPED);
+ }
+
+ TIntermSequence postTransformPrependStatements;
+ TIntermSequence *writeStatements = &appendStatements;
+ TOperator assignmentOperator = EOpAssign;
+
+ if (isWrite)
+ {
+ TIntermTyped *valueExpression = readExpression;
+
+ if (!valueExpression)
+ {
+ // If there's already a read expression, this was an inout parameter and
+ // |valueExpression| will contain the temp variable that was passed to the function
+ // instead.
+ //
+ // If not, then the modification is either through being passed as an out parameter
+ // to a function, or an assignment. In the former case, create a temp variable to
+ // be passed to the function. In the latter case, create a temp variable that holds
+ // the right hand side expression.
+ //
+ // In either case, use that temp value as the value to assign to |baseExpression|.
+
+ TVariable *temp =
+ CreateTempVariable(mSymbolTable, &originalExpression->getAsTyped()->getType());
+ TIntermDeclaration *tempDecl = nullptr;
+
+ valueExpression = new TIntermSymbol(temp);
+
+ TIntermBinary *assignment = accessor->getAsBinaryNode();
+ if (assignment)
+ {
+ assignmentOperator = assignment->getOp();
+ ASSERT(IsAssignment(assignmentOperator));
+
+ // We are converting the assignment to the left-hand side of an expression in
+ // the form M=exp. A subexpression of exp itself could require a
+ // transformation. This complicates things as there would be two replacements:
+ //
+ // - Replace M=exp with temp (because the return value of the assignment could
+ // be used)
+ // - Replace exp with exp2, where parent is M=exp
+ //
+ // The second replacement however is ineffective as the whole of M=exp is
+ // already transformed. What's worse, M=exp is transformed without taking exp's
+ // transformations into account. To address this issue, this same traverser is
+ // called on the right-hand side expression, with a special flag such that it
+ // only processes that expression.
+ //
+ RewriteRowMajorMatricesTraverser *outerTraverser =
+ mOuterTraverser ? mOuterTraverser : this;
+ RewriteRowMajorMatricesTraverser rhsTraverser(
+ mSymbolTable, outerTraverser, mInterfaceBlockMap,
+ mInterfaceBlockFieldConvertedIn, mStructMapOut, mCopyFunctionDefinitionsOut,
+ assignment);
+ getRootNode()->traverse(&rhsTraverser);
+ bool valid = rhsTraverser.updateTree(mCompiler, getRootNode());
+ ASSERT(valid);
+
+ tempDecl = CreateTempInitDeclarationNode(temp, assignment->getRight());
+
+ // Replace the whole assignment expression with the right-hand side as a read
+ // expression, in case the result of the assignment is used. For example, this
+ // transforms:
+ //
+ // if ((M += exp) == X)
+ // {
+ // // use M
+ // }
+ //
+ // to:
+ //
+ // temp = exp;
+ // M += transform(temp);
+ // if (transform(M) == X)
+ // {
+ // // use M
+ // }
+ //
+ // Note that in this case the assignment to M must be prepended in the parent
+ // block. In contrast, when sent to a function, the assignment to M should be
+ // done after the current function call is done.
+ //
+ // If the read from M itself (to replace assigmnet) needs to generate extra
+ // statements, they should be appended after the statements that write to M.
+ // These statements are stored in postTransformPrependStatements and appended to
+ // prependStatements in the end.
+ //
+ writeStatements = &prependStatements;
+
+ TIntermTyped *assignmentResultExpression = transformReadExpression(
+ baseExpression->deepCopy(), primaryIndex, &secondaryIndices, structure,
+ &postTransformPrependStatements);
+
+ // Replace the whole assignment, instead of just the right hand side.
+ TIntermNode *accessorParent = getAncestorNode(accessorIndex + 1);
+ queueReplacementWithParent(accessorParent, accessor, assignmentResultExpression,
+ OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ tempDecl = CreateTempDeclarationNode(temp);
+
+ // Replace the write expression (a function call argument) with the temp
+ // variable.
+ queueReplacementWithParent(accessor, originalExpression, valueExpression,
+ OriginalNode::IS_DROPPED);
+ }
+ prependStatements.push_back(tempDecl);
+ }
+
+ if (isRead)
+ {
+ baseExpression = baseExpression->deepCopy();
+ }
+ transformWriteExpression(baseExpression, primaryIndex, &secondaryIndices, structure,
+ valueExpression, assignmentOperator, writeStatements);
+ }
+
+ prependStatements.insert(prependStatements.end(), postTransformPrependStatements.begin(),
+ postTransformPrependStatements.end());
+
+ RewriteRowMajorMatricesTraverser *traverser = mOuterTraverser ? mOuterTraverser : this;
+ traverser->insertStatementsInParentBlock(prependStatements, appendStatements);
+ }
+
+ TIntermTyped *transformReadExpression(TIntermTyped *baseExpression,
+ TIntermNode *primaryIndex,
+ TIntermSequence *secondaryIndices,
+ const TStructure *structure,
+ TIntermSequence *prependStatements)
+ {
+ const TType &baseExpressionType = baseExpression->getType();
+
+ if (structure)
+ {
+ ASSERT(primaryIndex == nullptr && secondaryIndices->empty());
+ ASSERT(mStructMapOut->count(structure) != 0);
+ ASSERT((*mStructMapOut)[structure].convertedStruct != nullptr);
+
+ // Declare copy-from-converted-to-original-struct function (if not already).
+ declareStructCopyToOriginal(structure);
+
+ const TFunction *copyToOriginal = (*mStructMapOut)[structure].copyToOriginal;
+
+ if (baseExpressionType.isArray())
+ {
+ // If base expression is an array, transform every element.
+ TransformArrayHelper transformHelper(baseExpression);
+
+ TIntermTyped *element = nullptr;
+ while ((element = transformHelper.getNextElement(nullptr, nullptr)) != nullptr)
+ {
+ TIntermTyped *transformedElement =
+ CreateStructCopyCall(copyToOriginal, element);
+ transformHelper.accumulateForRead(mSymbolTable, transformedElement,
+ prependStatements);
+ }
+ return transformHelper.constructReadTransformExpression();
+ }
+ else
+ {
+ // If not reading an array, the result is simply a call to this function with the
+ // base expression.
+ return CreateStructCopyCall(copyToOriginal, baseExpression);
+ }
+ }
+
+ // If not indexed, the result is transpose(exp)
+ if (primaryIndex == nullptr)
+ {
+ ASSERT(secondaryIndices->empty());
+
+ if (baseExpressionType.isArray())
+ {
+ // If array, transpose every element.
+ TransformArrayHelper transformHelper(baseExpression);
+
+ TIntermTyped *element = nullptr;
+ while ((element = transformHelper.getNextElement(nullptr, nullptr)) != nullptr)
+ {
+ TIntermTyped *transformedElement = CreateTransposeCall(mSymbolTable, element);
+ transformHelper.accumulateForRead(mSymbolTable, transformedElement,
+ prependStatements);
+ }
+ return transformHelper.constructReadTransformExpression();
+ }
+ else
+ {
+ return CreateTransposeCall(mSymbolTable, baseExpression);
+ }
+ }
+
+ // If indexed the result is a vector (or just one element) where the primary and secondary
+ // indices are swapped.
+ ASSERT(!secondaryIndices->empty());
+
+ TOperator primaryIndexOp = GetIndexOp(primaryIndex);
+ TIntermTyped *primaryIndexAsTyped = primaryIndex->getAsTyped();
+
+ TIntermSequence transposedColumn;
+ for (TIntermNode *secondaryIndex : *secondaryIndices)
+ {
+ TOperator secondaryIndexOp = GetIndexOp(secondaryIndex);
+ TIntermTyped *secondaryIndexAsTyped = secondaryIndex->getAsTyped();
+
+ TIntermBinary *colIndexed = new TIntermBinary(
+ secondaryIndexOp, baseExpression->deepCopy(), secondaryIndexAsTyped->deepCopy());
+ TIntermBinary *colRowIndexed =
+ new TIntermBinary(primaryIndexOp, colIndexed, primaryIndexAsTyped->deepCopy());
+
+ transposedColumn.push_back(colRowIndexed);
+ }
+
+ if (secondaryIndices->size() == 1)
+ {
+ // If only one element, return that directly.
+ return transposedColumn.front()->getAsTyped();
+ }
+
+ // Otherwise create a constructor with the appropriate dimension.
+ TType *vecType = new TType(baseExpressionType.getBasicType(), secondaryIndices->size());
+ return TIntermAggregate::CreateConstructor(*vecType, &transposedColumn);
+ }
+
+ void transformWriteExpression(TIntermTyped *baseExpression,
+ TIntermNode *primaryIndex,
+ TIntermSequence *secondaryIndices,
+ const TStructure *structure,
+ TIntermTyped *valueExpression,
+ TOperator assignmentOperator,
+ TIntermSequence *writeStatements)
+ {
+ const TType &baseExpressionType = baseExpression->getType();
+
+ if (structure)
+ {
+ ASSERT(primaryIndex == nullptr && secondaryIndices->empty());
+ ASSERT(mStructMapOut->count(structure) != 0);
+ ASSERT((*mStructMapOut)[structure].convertedStruct != nullptr);
+
+ // Declare copy-to-converted-from-original-struct function (if not already).
+ declareStructCopyFromOriginal(structure);
+
+ // The result is call to this function with the value expression assigned to base
+ // expression.
+ const TFunction *copyFromOriginal = (*mStructMapOut)[structure].copyFromOriginal;
+
+ if (baseExpressionType.isArray())
+ {
+ // If array, assign every element.
+ TransformArrayHelper transformHelper(baseExpression);
+
+ TIntermTyped *element = nullptr;
+ TIntermTyped *valueElement = nullptr;
+ while ((element = transformHelper.getNextElement(valueExpression, &valueElement)) !=
+ nullptr)
+ {
+ TIntermTyped *functionCall =
+ CreateStructCopyCall(copyFromOriginal, valueElement);
+ writeStatements->push_back(new TIntermBinary(EOpAssign, element, functionCall));
+ }
+ }
+ else
+ {
+ TIntermTyped *functionCall =
+ CreateStructCopyCall(copyFromOriginal, valueExpression->deepCopy());
+ writeStatements->push_back(
+ new TIntermBinary(EOpAssign, baseExpression, functionCall));
+ }
+
+ return;
+ }
+
+ // If not indexed, the result is transpose(exp)
+ if (primaryIndex == nullptr)
+ {
+ ASSERT(secondaryIndices->empty());
+
+ if (baseExpressionType.isArray())
+ {
+ // If array, assign every element.
+ TransformArrayHelper transformHelper(baseExpression);
+
+ TIntermTyped *element = nullptr;
+ TIntermTyped *valueElement = nullptr;
+ while ((element = transformHelper.getNextElement(valueExpression, &valueElement)) !=
+ nullptr)
+ {
+ TIntermTyped *valueTransposed = CreateTransposeCall(mSymbolTable, valueElement);
+ writeStatements->push_back(
+ new TIntermBinary(EOpAssign, element, valueTransposed));
+ }
+ }
+ else
+ {
+ TIntermTyped *valueTransposed =
+ CreateTransposeCall(mSymbolTable, valueExpression->deepCopy());
+ writeStatements->push_back(
+ new TIntermBinary(assignmentOperator, baseExpression, valueTransposed));
+ }
+
+ return;
+ }
+
+ // If indexed, create one assignment per secondary index. If the right-hand side is a
+ // scalar, it's used with every assignment. If it's a vector, the assignment is
+ // per-component. The right-hand side cannot be a matrix as that would imply left-hand
+ // side being a matrix too, which is covered above where |primaryIndex == nullptr|.
+ ASSERT(!secondaryIndices->empty());
+
+ bool isValueExpressionScalar = valueExpression->getType().getNominalSize() == 1;
+ ASSERT(isValueExpressionScalar || valueExpression->getType().getNominalSize() ==
+ static_cast<int>(secondaryIndices->size()));
+
+ TOperator primaryIndexOp = GetIndexOp(primaryIndex);
+ TIntermTyped *primaryIndexAsTyped = primaryIndex->getAsTyped();
+
+ for (TIntermNode *secondaryIndex : *secondaryIndices)
+ {
+ TOperator secondaryIndexOp = GetIndexOp(secondaryIndex);
+ TIntermTyped *secondaryIndexAsTyped = secondaryIndex->getAsTyped();
+
+ TIntermBinary *colIndexed = new TIntermBinary(
+ secondaryIndexOp, baseExpression->deepCopy(), secondaryIndexAsTyped->deepCopy());
+ TIntermBinary *colRowIndexed =
+ new TIntermBinary(primaryIndexOp, colIndexed, primaryIndexAsTyped->deepCopy());
+
+ TIntermTyped *valueExpressionIndexed = valueExpression->deepCopy();
+ if (!isValueExpressionScalar)
+ {
+ valueExpressionIndexed = new TIntermBinary(secondaryIndexOp, valueExpressionIndexed,
+ secondaryIndexAsTyped->deepCopy());
+ }
+
+ writeStatements->push_back(
+ new TIntermBinary(assignmentOperator, colRowIndexed, valueExpressionIndexed));
+ }
+ }
+
+ const TFunction *getCopyStructFieldFunction(const TType *fromFieldType,
+ const TType *toFieldType,
+ bool isCopyToOriginal)
+ {
+ ASSERT(fromFieldType->getStruct());
+ ASSERT(toFieldType->getStruct());
+
+ // If copying from or to the original struct, the "to" field struct could require
+ // conversion to or from the "from" field struct. |isCopyToOriginal| tells us if we
+ // should expect to find toField or fromField in mStructMapOut, if true or false
+ // respectively.
+ const TFunction *fieldCopyFunction = nullptr;
+ if (isCopyToOriginal)
+ {
+ const TStructure *toFieldStruct = toFieldType->getStruct();
+
+ auto iter = mStructMapOut->find(toFieldStruct);
+ if (iter != mStructMapOut->end())
+ {
+ declareStructCopyToOriginal(toFieldStruct);
+ fieldCopyFunction = iter->second.copyToOriginal;
+ }
+ }
+ else
+ {
+ const TStructure *fromFieldStruct = fromFieldType->getStruct();
+
+ auto iter = mStructMapOut->find(fromFieldStruct);
+ if (iter != mStructMapOut->end())
+ {
+ declareStructCopyFromOriginal(fromFieldStruct);
+ fieldCopyFunction = iter->second.copyFromOriginal;
+ }
+ }
+
+ return fieldCopyFunction;
+ }
+
+ void addFieldCopy(TIntermBlock *body,
+ TIntermTyped *to,
+ TIntermTyped *from,
+ bool isCopyToOriginal)
+ {
+ const TType &fromType = from->getType();
+ const TType &toType = to->getType();
+
+ TIntermTyped *rhs = from;
+
+ if (fromType.getStruct())
+ {
+ const TFunction *fieldCopyFunction =
+ getCopyStructFieldFunction(&fromType, &toType, isCopyToOriginal);
+
+ if (fieldCopyFunction)
+ {
+ rhs = CreateStructCopyCall(fieldCopyFunction, from);
+ }
+ }
+ else if (fromType.isMatrix())
+ {
+ rhs = CreateTransposeCall(mSymbolTable, from);
+ }
+
+ body->appendStatement(new TIntermBinary(EOpAssign, to, rhs));
+ }
+
+ TFunction *declareStructCopy(const TStructure *from,
+ const TStructure *to,
+ bool isCopyToOriginal)
+ {
+ TType *fromType = new TType(from, true);
+ TType *toType = new TType(to, true);
+
+ // Create the parameter and return value variables.
+ TVariable *fromVar = new TVariable(mSymbolTable, ImmutableString("from"), fromType,
+ SymbolType::AngleInternal);
+ TVariable *toVar =
+ new TVariable(mSymbolTable, ImmutableString("to"), toType, SymbolType::AngleInternal);
+
+ TIntermSymbol *fromSymbol = new TIntermSymbol(fromVar);
+ TIntermSymbol *toSymbol = new TIntermSymbol(toVar);
+
+ // Create the function body as statements are generated.
+ TIntermBlock *body = new TIntermBlock;
+
+ // Declare the result variable.
+ TIntermDeclaration *toDecl = new TIntermDeclaration();
+ toDecl->appendDeclarator(toSymbol);
+ body->appendStatement(toDecl);
+
+ // Iterate over fields of the struct and copy one by one, transposing the matrices. If a
+ // struct is encountered that requires a transformation, this function is recursively
+ // called. As a result, it is important that the copy functions are placed in the code in
+ // order.
+ const TFieldList &fromFields = from->fields();
+ const TFieldList &toFields = to->fields();
+ ASSERT(fromFields.size() == toFields.size());
+
+ for (size_t fieldIndex = 0; fieldIndex < fromFields.size(); ++fieldIndex)
+ {
+ TIntermTyped *fieldIndexNode = CreateIndexNode(static_cast<int>(fieldIndex));
+
+ TIntermTyped *fromField =
+ new TIntermBinary(EOpIndexDirectStruct, fromSymbol->deepCopy(), fieldIndexNode);
+ TIntermTyped *toField = new TIntermBinary(EOpIndexDirectStruct, toSymbol->deepCopy(),
+ fieldIndexNode->deepCopy());
+
+ const TType *fromFieldType = fromFields[fieldIndex]->type();
+ bool isStructOrMatrix = fromFieldType->getStruct() || fromFieldType->isMatrix();
+
+ if (fromFieldType->isArray() && isStructOrMatrix)
+ {
+ // If struct or matrix array, we need to copy element by element.
+ TransformArrayHelper transformHelper(toField);
+
+ TIntermTyped *toElement = nullptr;
+ TIntermTyped *fromElement = nullptr;
+ while ((toElement = transformHelper.getNextElement(fromField, &fromElement)) !=
+ nullptr)
+ {
+ addFieldCopy(body, toElement, fromElement, isCopyToOriginal);
+ }
+ }
+ else
+ {
+ addFieldCopy(body, toField, fromField, isCopyToOriginal);
+ }
+ }
+
+ // Add return statement.
+ body->appendStatement(new TIntermBranch(EOpReturn, toSymbol->deepCopy()));
+
+ // Declare the function
+ TFunction *copyFunction = new TFunction(mSymbolTable, kEmptyImmutableString,
+ SymbolType::AngleInternal, toType, true);
+ copyFunction->addParameter(fromVar);
+
+ TIntermFunctionDefinition *functionDef =
+ CreateInternalFunctionDefinitionNode(*copyFunction, body);
+ mCopyFunctionDefinitionsOut->push_back(functionDef);
+
+ return copyFunction;
+ }
+
+ void declareStructCopyFromOriginal(const TStructure *structure)
+ {
+ StructConversionData *structData = &(*mStructMapOut)[structure];
+ if (structData->copyFromOriginal)
+ {
+ return;
+ }
+
+ structData->copyFromOriginal =
+ declareStructCopy(structure, structData->convertedStruct, false);
+ }
+
+ void declareStructCopyToOriginal(const TStructure *structure)
+ {
+ StructConversionData *structData = &(*mStructMapOut)[structure];
+ if (structData->copyToOriginal)
+ {
+ return;
+ }
+
+ structData->copyToOriginal =
+ declareStructCopy(structData->convertedStruct, structure, true);
+ }
+
+ TCompiler *mCompiler;
+
+ // This traverser can call itself to transform a subexpression before moving on. However, it
+ // needs to accumulate conversion functions in inner passes. The fields below marked with Out
+ // or In are inherited from the outer pass (for inner passes), or point to storage fields in
+ // mOuterPass (for the outer pass). The latter should not be used by the inner passes as they
+ // would be empty, so they are placed inside a struct to make them explicit.
+ struct
+ {
+ StructMap structMap;
+ InterfaceBlockMap interfaceBlockMap;
+ InterfaceBlockFieldConverted interfaceBlockFieldConverted;
+ TIntermSequence copyFunctionDefinitions;
+ } mOuterPass;
+
+ // A map from structures with matrices to their converted version.
+ StructMap *mStructMapOut;
+ // A map from interface block instances with row-major matrices to their converted variable. If
+ // an interface block is nameless, its fields are placed in this map instead. When a variable
+ // in this map is encountered, it signals the start of an expression that my need conversion,
+ // which is either "interfaceBlock.field..." or "field..." if nameless.
+ InterfaceBlockMap *mInterfaceBlockMap;
+ // A map from interface block fields to whether they need to be converted. If a field was
+ // already column-major, it shouldn't be transposed.
+ const InterfaceBlockFieldConverted &mInterfaceBlockFieldConvertedIn;
+
+ TIntermSequence *mCopyFunctionDefinitionsOut;
+
+ // If set, it's an inner pass and this will point to the outer pass traverser. All statement
+ // insertions are stored in the outer traverser and applied at once in the end. This prevents
+ // the inner passes from adding statements which invalidates the outer traverser's statement
+ // position tracking.
+ RewriteRowMajorMatricesTraverser *mOuterTraverser;
+
+ // If set, it's an inner pass that should only process the right-hand side of this particular
+ // node.
+ TIntermBinary *mInnerPassRoot;
+ bool mIsProcessingInnerPassSubtree;
+};
+
+} // anonymous namespace
+
+bool RewriteRowMajorMatrices(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ RewriteRowMajorMatricesTraverser traverser(compiler, symbolTable);
+ root->traverse(&traverser);
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(root);
+ root->insertChildNodes(firstFunctionIndex, *traverser.getStructCopyFunctions());
+
+ return compiler->validateAST(root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h
new file mode 100644
index 0000000000..2f3577248e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h
@@ -0,0 +1,37 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteRowMajorMatrices: Change row-major matrices to column-major in uniform and storage
+// buffers.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEROWMAJORMATRICES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEROWMAJORMATRICES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+#if (defined(ANGLE_ENABLE_GLSL) || defined(ANGLE_ENABLE_METAL)) && \
+ defined(ANGLE_ENABLE_APPLE_WORKAROUNDS)
+[[nodiscard]] bool RewriteRowMajorMatrices(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+#else
+[[nodiscard]] ANGLE_INLINE bool RewriteRowMajorMatrices(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEROWMAJORMATRICES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.cpp
new file mode 100644
index 0000000000..4aa8a28203
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.cpp
@@ -0,0 +1,97 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.h"
+
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class Traverser : public TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool Apply(TCompiler *compiler, TIntermNode *root);
+
+ private:
+ Traverser();
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+ void nextIteration();
+
+ bool mFound = false;
+};
+
+// static
+bool Traverser::Apply(TCompiler *compiler, TIntermNode *root)
+{
+ Traverser traverser;
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.mFound)
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.mFound);
+
+ return true;
+}
+
+Traverser::Traverser() : TIntermTraverser(true, false, false) {}
+
+void Traverser::nextIteration()
+{
+ mFound = false;
+}
+
+bool Traverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ if (mFound)
+ {
+ return false;
+ }
+
+ // Detect if the current operator is unary minus operator.
+ if (node->getOp() != EOpNegative)
+ {
+ return true;
+ }
+
+ // Detect if the current operand is a float variable.
+ TIntermTyped *fValue = node->getOperand();
+ if (!fValue->getType().isScalarFloat())
+ {
+ return true;
+ }
+
+ // 0.0 - float
+ TIntermTyped *zero = CreateZeroNode(fValue->getType());
+ zero->setLine(fValue->getLine());
+ TIntermBinary *sub = new TIntermBinary(EOpSub, zero, fValue);
+ sub->setLine(fValue->getLine());
+
+ queueReplacement(sub, OriginalNode::IS_DROPPED);
+
+ mFound = true;
+ return false;
+}
+
+} // anonymous namespace
+
+bool RewriteUnaryMinusOperatorFloat(TCompiler *compiler, TIntermNode *root)
+{
+ return Traverser::Apply(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.h
new file mode 100644
index 0000000000..30c4d25d01
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.h
@@ -0,0 +1,31 @@
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Rewrite "-float" to "0.0 - float" to work around unary minus operator on float issue on Intel Mac
+// OSX 10.11.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEUNARYMINUSOPERATORFLOAT_H_
+#define COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEUNARYMINUSOPERATORFLOAT_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+#if defined(ANGLE_ENABLE_GLSL) && defined(ANGLE_ENABLE_APPLE_WORKAROUNDS)
+[[nodiscard]] bool RewriteUnaryMinusOperatorFloat(TCompiler *compiler, TIntermNode *root);
+#else
+[[nodiscard]] ANGLE_INLINE bool RewriteUnaryMinusOperatorFloat(TCompiler *compiler,
+ TIntermNode *root)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEUNARYMINUSOPERATORFLOAT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.cpp
new file mode 100644
index 0000000000..55e2f8b971
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.cpp
@@ -0,0 +1,74 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// "x || y" is equivalent to "x ? true : y".
+TIntermTernary *UnfoldOR(TIntermTyped *x, TIntermTyped *y)
+{
+ return new TIntermTernary(x, CreateBoolNode(true), y);
+}
+
+// "x && y" is equivalent to "x ? y : false".
+TIntermTernary *UnfoldAND(TIntermTyped *x, TIntermTyped *y)
+{
+ return new TIntermTernary(x, y, CreateBoolNode(false));
+}
+
+// This traverser identifies all the short circuit binary nodes that need to
+// be replaced, and creates the corresponding replacement nodes. However,
+// the actual replacements happen after the traverse through updateTree().
+
+class UnfoldShortCircuitASTTraverser : public TIntermTraverser
+{
+ public:
+ UnfoldShortCircuitASTTraverser() : TIntermTraverser(true, false, false) {}
+
+ bool visitBinary(Visit visit, TIntermBinary *) override;
+};
+
+bool UnfoldShortCircuitASTTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ TIntermTernary *replacement = nullptr;
+
+ switch (node->getOp())
+ {
+ case EOpLogicalOr:
+ replacement = UnfoldOR(node->getLeft(), node->getRight());
+ break;
+ case EOpLogicalAnd:
+ replacement = UnfoldAND(node->getLeft(), node->getRight());
+ break;
+ default:
+ break;
+ }
+ if (replacement)
+ {
+ queueReplacement(replacement, OriginalNode::IS_DROPPED);
+ }
+ return true;
+}
+
+} // anonymous namespace
+
+bool UnfoldShortCircuitAST(TCompiler *compiler, TIntermBlock *root)
+{
+ UnfoldShortCircuitASTTraverser traverser;
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h
new file mode 100644
index 0000000000..648c7190a9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// UnfoldShortCircuitAST is an AST traverser to replace short-circuiting
+// operations with ternary operations.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_APPLE_UNFOLDSHORTCIRCUITAST_H_
+#define COMPILER_TRANSLATOR_TREEOPS_APPLE_UNFOLDSHORTCIRCUITAST_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+
+#if defined(ANGLE_ENABLE_GLSL) && defined(ANGLE_ENABLE_APPLE_WORKAROUNDS)
+[[nodiscard]] bool UnfoldShortCircuitAST(TCompiler *compiler, TIntermBlock *root);
+#else
+[[nodiscard]] ANGLE_INLINE bool UnfoldShortCircuitAST(TCompiler *compiler, TIntermBlock *root)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_APPLE_UNFOLDSHORTCIRCUITAST_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.cpp
new file mode 100644
index 0000000000..8790c4f5f2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.cpp
@@ -0,0 +1,61 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// AddDefaultReturnStatements.cpp: Add default return statements to functions that do not end in a
+// return.
+//
+
+#include "compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+bool NeedsReturnStatement(TIntermFunctionDefinition *node, TType *returnType)
+{
+ *returnType = node->getFunctionPrototype()->getType();
+ if (returnType->getBasicType() == EbtVoid)
+ {
+ return false;
+ }
+
+ TIntermBlock *bodyNode = node->getBody();
+ TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode();
+ if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+bool AddDefaultReturnStatements(TCompiler *compiler, TIntermBlock *root)
+{
+ TType returnType;
+ for (TIntermNode *node : *root->getSequence())
+ {
+ TIntermFunctionDefinition *definition = node->getAsFunctionDefinition();
+ if (definition != nullptr && NeedsReturnStatement(definition, &returnType))
+ {
+ TIntermBranch *branch = new TIntermBranch(EOpReturn, CreateZeroNode(returnType));
+
+ TIntermBlock *bodyNode = definition->getBody();
+ bodyNode->getSequence()->push_back(branch);
+ }
+ }
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h
new file mode 100644
index 0000000000..52b601514c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// AddDefaultReturnStatements.h: Add default return statements to functions that do not end in a
+// return.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_ADDDEFAULTRETURNSTATEMENTS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_ADDDEFAULTRETURNSTATEMENTS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+
+[[nodiscard]] bool AddDefaultReturnStatements(TCompiler *compiler, TIntermBlock *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_ADDDEFAULTRETURNSTATEMENTS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.cpp
new file mode 100644
index 0000000000..d9a0c9bebc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.cpp
@@ -0,0 +1,82 @@
+//
+// Copyright 2022 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h"
+
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class AggregateAssignArraysInSSBOsTraverser : public TIntermTraverser
+{
+ public:
+ AggregateAssignArraysInSSBOsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable)
+ {}
+
+ protected:
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ // Replace all aggregate assignments to arrays in SSBOs with element-by-element assignments.
+ // TODO(anglebug.com/7363): this implementation only works for the simple case (assignment
+ // statement), not more complex cases such as assignment-as-expression or functions with
+ // side effects in the RHS.
+
+ if (node->getOp() != EOpAssign)
+ {
+ return true;
+ }
+ else if (!node->getLeft()->getType().isArray())
+ {
+ return true;
+ }
+ else if (!IsInShaderStorageBlock(node->getLeft()))
+ {
+ return true;
+ }
+ const TType *mediumpIndexType = StaticType::Get<EbtInt, EbpMedium, EvqTemporary, 1, 1>();
+ auto *indexVariable = CreateTempVariable(mSymbolTable, mediumpIndexType);
+ auto *indexInit =
+ CreateTempInitDeclarationNode(indexVariable, CreateZeroNode(indexVariable->getType()));
+ auto *arraySizeNode = CreateIndexNode(node->getOutermostArraySize());
+ auto *indexSymbolNode = CreateTempSymbolNode(indexVariable);
+ auto *cond = new TIntermBinary(EOpLessThan, indexSymbolNode->deepCopy(), arraySizeNode);
+ auto *indexIncrement =
+ new TIntermUnary(EOpPreIncrement, indexSymbolNode->deepCopy(), nullptr);
+ auto *forLoopBody = new TIntermBlock();
+ auto *indexedLeft =
+ new TIntermBinary(EOpIndexDirect, node->getLeft(), indexSymbolNode->deepCopy());
+ auto *indexedRight =
+ new TIntermBinary(EOpIndexDirect, node->getRight(), indexSymbolNode->deepCopy());
+ auto *assign = new TIntermBinary(TOperator::EOpAssign, indexedLeft, indexedRight);
+ forLoopBody->appendStatement(assign);
+ auto *forLoop =
+ new TIntermLoop(ELoopFor, indexInit, cond, indexIncrement, EnsureBlock(forLoopBody));
+ queueReplacement(forLoop, OriginalNode::IS_DROPPED);
+ return false;
+ }
+};
+
+} // namespace
+
+bool AggregateAssignArraysInSSBOs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ AggregateAssignArraysInSSBOsTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h
new file mode 100644
index 0000000000..ce965bb002
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h
@@ -0,0 +1,23 @@
+//
+// Copyright 2022 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_AGGREGATEASSIGNARRAYSINSSBOS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_AGGREGATEASSIGNARRAYSINSSBOS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool AggregateAssignArraysInSSBOs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_AGGREGATEASSIGNARRAYSINSSBOS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.cpp
new file mode 100644
index 0000000000..4293f4c4da
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.cpp
@@ -0,0 +1,76 @@
+//
+// Copyright 2022 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.h"
+
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class AggregateAssignStructsInSSBOsTraverser : public TIntermTraverser
+{
+ public:
+ AggregateAssignStructsInSSBOsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable)
+ {}
+
+ protected:
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ // Replace all assignments to structs in SSBOs with field-by-field asignments.
+ // TODO(anglebug.com/7362): this implementation only works for the simple case (assignment
+ // statement), not more complex cases such as assignment-as-expression or functions with
+ // side effects in the RHS.
+ const TStructure *s;
+ if (node->getOp() != EOpAssign)
+ {
+ return true;
+ }
+ else if (!IsInShaderStorageBlock(node->getLeft()))
+ {
+ return true;
+ }
+ else if (!(s = node->getLeft()->getType().getStruct()))
+ {
+ return true;
+ }
+ ASSERT(node->getRight()->getType().getStruct() == s);
+ auto *block = new TIntermBlock();
+ for (int i = 0; i < static_cast<int>(s->fields().size()); ++i)
+ {
+ auto *left = new TIntermBinary(EOpIndexDirectStruct, node->getLeft()->deepCopy(),
+ CreateIndexNode(i));
+ auto *right = new TIntermBinary(EOpIndexDirectStruct, node->getRight()->deepCopy(),
+ CreateIndexNode(i));
+ auto *assign = new TIntermBinary(TOperator::EOpAssign, left, right);
+ block->appendStatement(assign);
+ }
+
+ queueReplacement(block, OriginalNode::IS_DROPPED);
+ return false;
+ }
+};
+
+} // namespace
+
+bool AggregateAssignStructsInSSBOs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ AggregateAssignStructsInSSBOsTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.h
new file mode 100644
index 0000000000..910345902b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.h
@@ -0,0 +1,23 @@
+//
+// Copyright 2022 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_AGGREGATEASSIGNSTRUCTSINSSBOS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_AGGREGATEASSIGNSTRUCTSINSSBOS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool AggregateAssignStructsInSSBOs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_AGGREGATEASSIGNSTRUCTSINSSBOS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.cpp
new file mode 100644
index 0000000000..54d8fc0808
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.cpp
@@ -0,0 +1,233 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The ArrayReturnValueToOutParameter function changes return values of an array type to out
+// parameters in function definitions, prototypes, and call sites.
+
+#include "compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h"
+
+#include <map>
+
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kReturnValueVariableName("angle_return");
+
+class ArrayReturnValueToOutParameterTraverser : private TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool apply(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+ private:
+ ArrayReturnValueToOutParameterTraverser(TSymbolTable *symbolTable);
+
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBranch(Visit visit, TIntermBranch *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+
+ TIntermAggregate *createReplacementCall(TIntermAggregate *originalCall,
+ TIntermTyped *returnValueTarget);
+
+ // Set when traversal is inside a function with array return value.
+ TIntermFunctionDefinition *mFunctionWithArrayReturnValue;
+
+ struct ChangedFunction
+ {
+ const TVariable *returnValueVariable;
+ const TFunction *func;
+ };
+
+ // Map from function symbol ids to the changed function.
+ std::map<int, ChangedFunction> mChangedFunctions;
+};
+
+TIntermAggregate *ArrayReturnValueToOutParameterTraverser::createReplacementCall(
+ TIntermAggregate *originalCall,
+ TIntermTyped *returnValueTarget)
+{
+ TIntermSequence replacementArguments;
+ TIntermSequence *originalArguments = originalCall->getSequence();
+ for (auto &arg : *originalArguments)
+ {
+ replacementArguments.push_back(arg);
+ }
+ replacementArguments.push_back(returnValueTarget);
+ ASSERT(originalCall->getFunction());
+ const TSymbolUniqueId &originalId = originalCall->getFunction()->uniqueId();
+ TIntermAggregate *replacementCall = TIntermAggregate::CreateFunctionCall(
+ *mChangedFunctions[originalId.get()].func, &replacementArguments);
+ replacementCall->setLine(originalCall->getLine());
+ return replacementCall;
+}
+
+bool ArrayReturnValueToOutParameterTraverser::apply(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ ArrayReturnValueToOutParameterTraverser arrayReturnValueToOutParam(symbolTable);
+ root->traverse(&arrayReturnValueToOutParam);
+ return arrayReturnValueToOutParam.updateTree(compiler, root);
+}
+
+ArrayReturnValueToOutParameterTraverser::ArrayReturnValueToOutParameterTraverser(
+ TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, true, symbolTable), mFunctionWithArrayReturnValue(nullptr)
+{}
+
+bool ArrayReturnValueToOutParameterTraverser::visitFunctionDefinition(
+ Visit visit,
+ TIntermFunctionDefinition *node)
+{
+ if (node->getFunctionPrototype()->isArray() && visit == PreVisit)
+ {
+ // Replacing the function header is done on visitFunctionPrototype().
+ mFunctionWithArrayReturnValue = node;
+ }
+ if (visit == PostVisit)
+ {
+ mFunctionWithArrayReturnValue = nullptr;
+ }
+ return true;
+}
+
+void ArrayReturnValueToOutParameterTraverser::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ if (node->isArray())
+ {
+ // Replace the whole prototype node with another node that has the out parameter
+ // added. Also set the function to return void.
+ const TSymbolUniqueId &functionId = node->getFunction()->uniqueId();
+ if (mChangedFunctions.find(functionId.get()) == mChangedFunctions.end())
+ {
+ TType *returnValueVariableType = new TType(node->getType());
+ returnValueVariableType->setQualifier(EvqParamOut);
+ ChangedFunction changedFunction;
+ changedFunction.returnValueVariable =
+ new TVariable(mSymbolTable, kReturnValueVariableName, returnValueVariableType,
+ SymbolType::AngleInternal);
+ TFunction *func = new TFunction(mSymbolTable, node->getFunction()->name(),
+ node->getFunction()->symbolType(),
+ StaticType::GetBasic<EbtVoid, EbpUndefined>(), false);
+ for (size_t i = 0; i < node->getFunction()->getParamCount(); ++i)
+ {
+ func->addParameter(node->getFunction()->getParam(i));
+ }
+ func->addParameter(changedFunction.returnValueVariable);
+ changedFunction.func = func;
+ mChangedFunctions[functionId.get()] = changedFunction;
+ }
+ TIntermFunctionPrototype *replacement =
+ new TIntermFunctionPrototype(mChangedFunctions[functionId.get()].func);
+ replacement->setLine(node->getLine());
+
+ queueReplacement(replacement, OriginalNode::IS_DROPPED);
+ }
+}
+
+bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ ASSERT(!node->isArray() || node->getOp() != EOpCallInternalRawFunction);
+ if (visit == PreVisit && node->isArray() && node->getOp() == EOpCallFunctionInAST)
+ {
+ // Handle call sites where the returned array is not assigned.
+ // Examples where f() is a function returning an array:
+ // 1. f();
+ // 2. another_array == f();
+ // 3. another_function(f());
+ // 4. return f();
+ // Cases 2 to 4 are already converted to simpler cases by
+ // SeparateExpressionsReturningArrays, so we only need to worry about the case where a
+ // function call returning an array forms an expression by itself.
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ if (parentBlock)
+ {
+ // replace
+ // f();
+ // with
+ // type s0[size]; f(s0);
+ TIntermSequence replacements;
+
+ // type s0[size];
+ TIntermDeclaration *returnValueDeclaration = nullptr;
+ TVariable *returnValue = DeclareTempVariable(mSymbolTable, new TType(node->getType()),
+ EvqTemporary, &returnValueDeclaration);
+ replacements.push_back(returnValueDeclaration);
+
+ // f(s0);
+ TIntermSymbol *returnValueSymbol = CreateTempSymbolNode(returnValue);
+ replacements.push_back(createReplacementCall(node, returnValueSymbol));
+ mMultiReplacements.emplace_back(parentBlock, node, std::move(replacements));
+ }
+ return false;
+ }
+ return true;
+}
+
+bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBranch *node)
+{
+ if (mFunctionWithArrayReturnValue && node->getFlowOp() == EOpReturn)
+ {
+ // Instead of returning a value, assign to the out parameter and then return.
+ TIntermSequence replacements;
+
+ TIntermTyped *expression = node->getExpression();
+ ASSERT(expression != nullptr);
+ const TSymbolUniqueId &functionId =
+ mFunctionWithArrayReturnValue->getFunction()->uniqueId();
+ ASSERT(mChangedFunctions.find(functionId.get()) != mChangedFunctions.end());
+ TIntermSymbol *returnValueSymbol =
+ new TIntermSymbol(mChangedFunctions[functionId.get()].returnValueVariable);
+ TIntermBinary *replacementAssignment =
+ new TIntermBinary(EOpAssign, returnValueSymbol, expression);
+ replacementAssignment->setLine(expression->getLine());
+ replacements.push_back(replacementAssignment);
+
+ TIntermBranch *replacementBranch = new TIntermBranch(EOpReturn, nullptr);
+ replacementBranch->setLine(node->getLine());
+ replacements.push_back(replacementBranch);
+
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(replacements));
+ }
+ return false;
+}
+
+bool ArrayReturnValueToOutParameterTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (node->getOp() == EOpAssign && node->getLeft()->isArray())
+ {
+ TIntermAggregate *rightAgg = node->getRight()->getAsAggregate();
+ ASSERT(rightAgg == nullptr || rightAgg->getOp() != EOpCallInternalRawFunction);
+ if (rightAgg != nullptr && rightAgg->getOp() == EOpCallFunctionInAST)
+ {
+ TIntermAggregate *replacementCall = createReplacementCall(rightAgg, node->getLeft());
+ queueReplacement(replacementCall, OriginalNode::IS_DROPPED);
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+bool ArrayReturnValueToOutParameter(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ return ArrayReturnValueToOutParameterTraverser::apply(compiler, root, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h
new file mode 100644
index 0000000000..ae8d04ae9a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The ArrayReturnValueToOutParameter function changes return values of an array type to out
+// parameters in function definitions, prototypes and call sites.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_ARRAYRETURNVALUETOOUTPARAMETER_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_ARRAYRETURNVALUETOOUTPARAMETER_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool ArrayReturnValueToOutParameter(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_ARRAYRETURNVALUETOOUTPARAMETER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.cpp
new file mode 100644
index 0000000000..908da7a8c2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.cpp
@@ -0,0 +1,110 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend
+// may record a variable as aliasing another. Sometimes the alias information gets garbled
+// so we work around this issue by breaking the aliasing chain in inner loops.
+
+#include "compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+// A HLSL compiler developer gave us more details on the root cause and the workaround needed:
+// The root problem is that if the HLSL compiler is applying aliasing information even on
+// incomplete simulations (in this case, a single pass). The bug is triggered by an assignment
+// that comes from a series of assignments, possibly with swizzled or ternary operators with
+// known conditionals, where the source is before the loop.
+// So, a workaround is to add a +0 term to variables the first time they are assigned to in
+// an inner loop (if they are declared in an outside scope, otherwise there is no need).
+// This will break the aliasing chain.
+
+// For simplicity here we add a +0 to any assignment that is in at least two nested loops. Because
+// the bug only shows up with swizzles, and ternary assignment, whole array or whole structure
+// assignment don't need a workaround.
+
+namespace sh
+{
+
+namespace
+{
+
+class AliasingBreaker : public TIntermTraverser
+{
+ public:
+ AliasingBreaker() : TIntermTraverser(true, false, true) {}
+
+ protected:
+ bool visitBinary(Visit visit, TIntermBinary *binary) override
+ {
+ if (visit != PreVisit)
+ {
+ return false;
+ }
+
+ if (mLoopLevel < 2 || !binary->isAssignment())
+ {
+ return true;
+ }
+
+ TIntermTyped *B = binary->getRight();
+ TType type = B->getType();
+
+ if (!type.isScalar() && !type.isVector() && !type.isMatrix())
+ {
+ return true;
+ }
+
+ if (type.isArray() || IsSampler(type.getBasicType()))
+ {
+ return true;
+ }
+
+ // We have a scalar / vector / matrix assignment with loop depth 2.
+ // Transform it from
+ // A = B
+ // to
+ // A = (B + typeof<B>(0));
+
+ TIntermBinary *bPlusZero = new TIntermBinary(EOpAdd, B, CreateZeroNode(type));
+ bPlusZero->setLine(B->getLine());
+
+ binary->replaceChildNode(B, bPlusZero);
+
+ return true;
+ }
+
+ bool visitLoop(Visit visit, TIntermLoop *loop) override
+ {
+ if (visit == PreVisit)
+ {
+ mLoopLevel++;
+ }
+ else
+ {
+ ASSERT(mLoopLevel > 0);
+ mLoopLevel--;
+ }
+
+ return true;
+ }
+
+ private:
+ int mLoopLevel = 0;
+};
+
+} // anonymous namespace
+
+bool BreakVariableAliasingInInnerLoops(TCompiler *compiler, TIntermNode *root)
+{
+ AliasingBreaker breaker;
+ root->traverse(&breaker);
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h
new file mode 100644
index 0000000000..455c7c322d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend
+// may record a variable as aliasing another. Sometimes the alias information gets garbled
+// so we work around this issue by breaking the aliasing chain in inner loops.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_BREAKVARIABLEALIASINGININNERLOOPS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_BREAKVARIABLEALIASINGININNERLOOPS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+[[nodiscard]] bool BreakVariableAliasingInInnerLoops(TCompiler *compiler, TIntermNode *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_BREAKVARIABLEALIASINGININNERLOOPS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.cpp
new file mode 100644
index 0000000000..e873db56cd
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.cpp
@@ -0,0 +1,152 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Implementation of the integer pow expressions HLSL bug workaround.
+// See header for more info.
+
+#include "compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.h"
+
+#include <cmath>
+#include <cstdlib>
+
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class Traverser : public TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool Apply(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+ private:
+ Traverser(TSymbolTable *symbolTable);
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ void nextIteration();
+
+ bool mFound = false;
+};
+
+// static
+bool Traverser::Apply(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ Traverser traverser(symbolTable);
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.mFound)
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.mFound);
+
+ return true;
+}
+
+Traverser::Traverser(TSymbolTable *symbolTable) : TIntermTraverser(true, false, false, symbolTable)
+{}
+
+void Traverser::nextIteration()
+{
+ mFound = false;
+}
+
+bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ if (mFound)
+ {
+ return false;
+ }
+
+ // Test 0: skip non-pow operators.
+ if (node->getOp() != EOpPow)
+ {
+ return true;
+ }
+
+ const TIntermSequence *sequence = node->getSequence();
+ ASSERT(sequence->size() == 2u);
+ const TIntermConstantUnion *constantExponent = sequence->at(1)->getAsConstantUnion();
+
+ // Test 1: check for a single constant.
+ if (!constantExponent || constantExponent->getNominalSize() != 1)
+ {
+ return true;
+ }
+
+ float exponentValue = constantExponent->getConstantValue()->getFConst();
+
+ // Test 2: exponentValue is in the problematic range.
+ if (exponentValue < -5.0f || exponentValue > 9.0f)
+ {
+ return true;
+ }
+
+ // Test 3: exponentValue is integer or pretty close to an integer.
+ if (std::abs(exponentValue - std::round(exponentValue)) > 0.0001f)
+ {
+ return true;
+ }
+
+ // Test 4: skip -1, 0, and 1
+ int exponent = static_cast<int>(std::round(exponentValue));
+ int n = std::abs(exponent);
+ if (n < 2)
+ {
+ return true;
+ }
+
+ // Potential problem case detected, apply workaround.
+
+ TIntermTyped *lhs = sequence->at(0)->getAsTyped();
+ ASSERT(lhs);
+
+ TIntermDeclaration *lhsVariableDeclaration = nullptr;
+ TVariable *lhsVariable =
+ DeclareTempVariable(mSymbolTable, lhs, EvqTemporary, &lhsVariableDeclaration);
+ insertStatementInParentBlock(lhsVariableDeclaration);
+
+ // Create a chain of n-1 multiples.
+ TIntermTyped *current = CreateTempSymbolNode(lhsVariable);
+ for (int i = 1; i < n; ++i)
+ {
+ TIntermBinary *mul = new TIntermBinary(EOpMul, current, CreateTempSymbolNode(lhsVariable));
+ mul->setLine(node->getLine());
+ current = mul;
+ }
+
+ // For negative pow, compute the reciprocal of the positive pow.
+ if (exponent < 0)
+ {
+ TConstantUnion *oneVal = new TConstantUnion();
+ oneVal->setFConst(1.0f);
+ TIntermConstantUnion *oneNode = new TIntermConstantUnion(oneVal, node->getType());
+ TIntermBinary *div = new TIntermBinary(EOpDiv, oneNode, current);
+ current = div;
+ }
+
+ queueReplacement(current, OriginalNode::IS_DROPPED);
+ mFound = true;
+ return false;
+}
+
+} // anonymous namespace
+
+bool ExpandIntegerPowExpressions(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ return Traverser::Apply(compiler, root, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.h
new file mode 100644
index 0000000000..2404fb08ac
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.h
@@ -0,0 +1,34 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This mutating tree traversal works around a bug in the HLSL compiler optimizer with "pow" that
+// manifests under the following conditions:
+//
+// - If pow() has a literal exponent value
+// - ... and this value is integer or within 10e-6 of an integer
+// - ... and it is in {-4, -3, -2, 2, 3, 4, 5, 6, 7, 8}
+//
+// The workaround is to replace the pow with a series of multiplies.
+// See http://anglebug.com/851
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_EXPANDINTEGERPOWEXPRESSIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_EXPANDINTEGERPOWEXPRESSIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool ExpandIntegerPowExpressions(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_EXPANDINTEGERPOWEXPRESSIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.cpp
new file mode 100644
index 0000000000..18d49814ac
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.cpp
@@ -0,0 +1,385 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RecordUniformBlocksWithLargeArrayMember.h:
+// Collect all uniform blocks which have one or more large array members,
+// and the array sizes are greater than or equal to 50. If some of them
+// satify some conditions, we will translate them to StructuredBuffers
+// on Direct3D backend.
+//
+
+#include "compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+// Only when a uniform block member's array size is greater than or equal to
+// kMinArraySizeUseStructuredBuffer, then we may translate the uniform block
+// to a StructuredBuffer on Direct3D backend.
+const unsigned int kMinArraySizeUseStructuredBuffer = 50u;
+
+// There is a maximum of D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT(128) slots that are
+// available for shader resources on Direct3D 11. When shader version is 300, we only use
+// D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT(16) slots for texture units. We allow StructuredBuffer
+// to use the maximum of 60 slots, that is enough here.
+const unsigned int kMaxAllowToUseRegisterCount = 60u;
+
+// Traverser that all uniform blocks which have one or more large array members, and the array
+// sizes are greater than or equal to 50.
+class UniformBlocksWithLargeArrayMemberTraverser : public TIntermTraverser
+{
+ public:
+ UniformBlocksWithLargeArrayMemberTraverser();
+
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ std::map<int, const TInterfaceBlock *> &getUniformBlockMayTranslation()
+ {
+ return mUniformBlockMayTranslation;
+ }
+ std::map<int, const TInterfaceBlock *> &getUniformBlockNotAllowTranslation()
+ {
+ return mUniformBlockNotAllowTranslation;
+ }
+ std::map<int, unsigned int> &getUniformBlockUsedRegisterCount()
+ {
+ return mUniformBlockUsedRegisterCount;
+ }
+ std::map<int, const TInterfaceBlock *> &getUniformBlockWithLargeArrayMember()
+ {
+ return mUniformBlockWithLargeArrayMember;
+ }
+
+ private:
+ std::map<int, const TInterfaceBlock *> mUniformBlockMayTranslation;
+ std::map<int, const TInterfaceBlock *> mUniformBlockNotAllowTranslation;
+ std::map<int, unsigned int> mUniformBlockUsedRegisterCount;
+ std::map<int, const TInterfaceBlock *> mUniformBlockWithLargeArrayMember;
+};
+
+UniformBlocksWithLargeArrayMemberTraverser::UniformBlocksWithLargeArrayMemberTraverser()
+ : TIntermTraverser(true, true, false)
+{}
+
+static bool IsSupportedTypeForStructuredBuffer(const TType &type)
+{
+ const TStructure *structure = type.getStruct();
+ const TLayoutMatrixPacking matrixPacking = type.getLayoutQualifier().matrixPacking;
+ if (structure)
+ {
+ const TFieldList &fields = structure->fields();
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ const TType &fieldType = *fields[i]->type();
+ // Do not allow the structure's member is array or structure.
+ if (!fieldType.isArray() && !fieldType.getStruct() &&
+ (fieldType.isScalar() || fieldType.isVector() ||
+ (fieldType.isMatrix() &&
+ ((matrixPacking != EmpRowMajor && fieldType.getRows() == 4) ||
+ (matrixPacking == EmpRowMajor && fieldType.getCols() == 4)))))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (type.isMatrix())
+ {
+ // Only supports the matrix types that we do not need to pad in a structure or an array
+ // explicitly.
+ return (matrixPacking != EmpRowMajor && type.getRows() == 4) ||
+ (matrixPacking == EmpRowMajor && type.getCols() == 4);
+ }
+ else
+ {
+ // Supports vector and scalar types in a structure or an array.
+ return true;
+ }
+}
+
+static bool CanTranslateUniformBlockToStructuredBuffer(const TInterfaceBlock &interfaceBlock)
+{
+ const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
+
+ if (blockStorage == EbsStd140 && interfaceBlock.fields().size() == 1u)
+ {
+ const TType &fieldType = *interfaceBlock.fields()[0]->type();
+ if (fieldType.getNumArraySizes() == 1u &&
+ fieldType.getOutermostArraySize() >= kMinArraySizeUseStructuredBuffer)
+ {
+ return IsSupportedTypeForStructuredBuffer(fieldType);
+ }
+ }
+
+ return false;
+}
+
+static bool FieldIsOrHasLargeArrayField(const TField &field)
+{
+ const TType *type = field.type();
+ if (type->getArraySizeProduct() >= kMinArraySizeUseStructuredBuffer)
+ {
+ return true;
+ }
+
+ const TStructure *structure = type->getStruct();
+ if (structure)
+ {
+ const TFieldList &fields = structure->fields();
+ bool hasLargeArrayField = false;
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ hasLargeArrayField = FieldIsOrHasLargeArrayField(*fields[i]);
+ if (hasLargeArrayField)
+ {
+ break;
+ }
+ }
+ return hasLargeArrayField;
+ }
+
+ return false;
+}
+
+static bool IsInterfaceBlockWithLargeArrayField(const TInterfaceBlock &interfaceBlock)
+{
+ const TFieldList &fields = interfaceBlock.fields();
+ bool isLargeArrayField = false;
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ isLargeArrayField = FieldIsOrHasLargeArrayField(*fields[i]);
+ if (isLargeArrayField)
+ {
+ break;
+ }
+ }
+
+ return isLargeArrayField;
+}
+
+void UniformBlocksWithLargeArrayMemberTraverser::visitSymbol(TIntermSymbol *node)
+{
+ const TVariable &variable = node->variable();
+ const TType &variableType = variable.getType();
+ TQualifier qualifier = variable.getType().getQualifier();
+
+ if (qualifier == EvqUniform)
+ {
+ const TInterfaceBlock *interfaceBlock = variableType.getInterfaceBlock();
+ if (interfaceBlock)
+ {
+ if (CanTranslateUniformBlockToStructuredBuffer(*interfaceBlock))
+ {
+ if (mUniformBlockMayTranslation.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockMayTranslation[interfaceBlock->uniqueId().get()] = interfaceBlock;
+ }
+
+ if (!variableType.isInterfaceBlock())
+ {
+ TIntermNode *accessor = getAncestorNode(0);
+ TIntermBinary *accessorAsBinary = accessor->getAsBinaryNode();
+ // The uniform block variable is array type, only indexing operator is allowed
+ // to operate on the variable, otherwise do not translate the uniform block to
+ // HLSL StructuredBuffer.
+ if (!accessorAsBinary ||
+ !(accessorAsBinary && (accessorAsBinary->getOp() == EOpIndexDirect ||
+ accessorAsBinary->getOp() == EOpIndexIndirect)))
+ {
+ if (mUniformBlockNotAllowTranslation.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockNotAllowTranslation[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ }
+ }
+ else
+ {
+ if (mUniformBlockUsedRegisterCount.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ // The uniform block is not an instanced one, so it only uses one
+ // register.
+ mUniformBlockUsedRegisterCount[interfaceBlock->uniqueId().get()] = 1;
+ }
+ }
+ }
+ else
+ {
+ if (mUniformBlockUsedRegisterCount.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ // The uniform block is an instanced one, the count of used registers
+ // depends on the array size of variable.
+ mUniformBlockUsedRegisterCount[interfaceBlock->uniqueId().get()] =
+ variableType.isArray() ? variableType.getOutermostArraySize() : 1;
+ }
+ }
+ }
+
+ if (interfaceBlock->blockStorage() == EbsStd140 &&
+ IsInterfaceBlockWithLargeArrayField(*interfaceBlock))
+ {
+ if (!variableType.isInterfaceBlock())
+ {
+ TIntermNode *accessor = getAncestorNode(0);
+ TIntermBinary *accessorAsBinary = accessor->getAsBinaryNode();
+ if (accessorAsBinary && (accessorAsBinary->getOp() == EOpIndexDirect ||
+ accessorAsBinary->getOp() == EOpIndexIndirect))
+ {
+ if (mUniformBlockWithLargeArrayMember.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockWithLargeArrayMember[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool UniformBlocksWithLargeArrayMemberTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ switch (node->getOp())
+ {
+ case EOpIndexDirect:
+ {
+ if (visit == PreVisit)
+ {
+ const TType &leftType = node->getLeft()->getType();
+ if (leftType.isInterfaceBlock())
+ {
+ const TInterfaceBlock *interfaceBlock = leftType.getInterfaceBlock();
+ if (CanTranslateUniformBlockToStructuredBuffer(*interfaceBlock) &&
+ mUniformBlockMayTranslation.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockMayTranslation[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ if (mUniformBlockUsedRegisterCount.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ // The uniform block is an instanced one, the count of used registers
+ // depends on the array size of variable.
+ mUniformBlockUsedRegisterCount[interfaceBlock->uniqueId().get()] =
+ leftType.isArray() ? leftType.getOutermostArraySize() : 1;
+ }
+ return false;
+ }
+
+ if (interfaceBlock->blockStorage() == EbsStd140 &&
+ IsInterfaceBlockWithLargeArrayField(*interfaceBlock))
+ {
+ if (mUniformBlockWithLargeArrayMember.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockWithLargeArrayMember[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ }
+ }
+ }
+ }
+ break;
+ }
+ case EOpIndexDirectInterfaceBlock:
+ {
+ if (visit == InVisit)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ node->getLeft()->getType().getInterfaceBlock();
+ if (CanTranslateUniformBlockToStructuredBuffer(*interfaceBlock))
+ {
+ TIntermNode *accessor = getAncestorNode(0);
+ TIntermBinary *accessorAsBinary = accessor->getAsBinaryNode();
+ // The uniform block variable is array type, only indexing operator is allowed
+ // to operate on the variable, otherwise do not translate the uniform block to
+ // HLSL StructuredBuffer.
+ if ((!accessorAsBinary ||
+ !(accessorAsBinary && (accessorAsBinary->getOp() == EOpIndexDirect ||
+ accessorAsBinary->getOp() == EOpIndexIndirect))) &&
+ mUniformBlockNotAllowTranslation.count(interfaceBlock->uniqueId().get()) ==
+ 0)
+ {
+ mUniformBlockNotAllowTranslation[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ return false;
+ }
+ }
+
+ if (interfaceBlock->blockStorage() == EbsStd140 &&
+ IsInterfaceBlockWithLargeArrayField(*interfaceBlock))
+ {
+ TIntermNode *accessor = getAncestorNode(0);
+ TIntermBinary *accessorAsBinary = accessor->getAsBinaryNode();
+ if (accessorAsBinary && (accessorAsBinary->getOp() == EOpIndexDirect ||
+ accessorAsBinary->getOp() == EOpIndexIndirect))
+ {
+ if (mUniformBlockWithLargeArrayMember.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockWithLargeArrayMember[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ }
+ }
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return true;
+}
+} // namespace
+
+bool RecordUniformBlocksWithLargeArrayMember(
+ TIntermNode *root,
+ std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap,
+ std::set<std::string> &slowCompilingUniformBlockSet)
+{
+ UniformBlocksWithLargeArrayMemberTraverser traverser;
+ root->traverse(&traverser);
+ std::map<int, const TInterfaceBlock *> &uniformBlockMayTranslation =
+ traverser.getUniformBlockMayTranslation();
+ std::map<int, const TInterfaceBlock *> &uniformBlockNotAllowTranslation =
+ traverser.getUniformBlockNotAllowTranslation();
+ std::map<int, unsigned int> &uniformBlockUsedRegisterCount =
+ traverser.getUniformBlockUsedRegisterCount();
+ std::map<int, const TInterfaceBlock *> &uniformBlockWithLargeArrayMember =
+ traverser.getUniformBlockWithLargeArrayMember();
+
+ unsigned int usedRegisterCount = 0;
+ for (auto &uniformBlock : uniformBlockMayTranslation)
+ {
+ if (uniformBlockNotAllowTranslation.count(uniformBlock.first) == 0)
+ {
+ usedRegisterCount += uniformBlockUsedRegisterCount[uniformBlock.first];
+ if (usedRegisterCount > kMaxAllowToUseRegisterCount)
+ {
+ break;
+ }
+ uniformBlockOptimizedMap[uniformBlock.first] = uniformBlock.second;
+ }
+ }
+
+ for (auto &uniformBlock : uniformBlockWithLargeArrayMember)
+ {
+ if (uniformBlockOptimizedMap.count(uniformBlock.first) == 0)
+ {
+ slowCompilingUniformBlockSet.insert(uniformBlock.second->name().data());
+ }
+ }
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h
new file mode 100644
index 0000000000..d7825c28cb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RecordUniformBlocksWithLargeArrayMember.h:
+// Collect all uniform blocks which have one or more large array members,
+// and the array sizes are greater than or equal to 50. If some of them
+// satify some conditions, we will translate them to StructuredBuffers
+// on Direct3D backend.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_RECORDUNIFORMBLOCKSWITHLARGEARRAYMEMBER_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_RECORDUNIFORMBLOCKSWITHLARGEARRAYMEMBER_H_
+
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+class TIntermNode;
+
+[[nodiscard]] bool RecordUniformBlocksWithLargeArrayMember(
+ TIntermNode *root,
+ std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap,
+ std::set<std::string> &slowCompilingUniformBlockSet);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_RECORDUNIFORMBLOCKSWITHLARGEARRAYMEMBER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.cpp
new file mode 100644
index 0000000000..6360f1083c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.cpp
@@ -0,0 +1,270 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveSwitchFallThrough.cpp: Remove fall-through from switch statements.
+// Note that it is unsafe to do further AST transformations on the AST generated
+// by this function. It leaves duplicate nodes in the AST making replacements
+// unreliable.
+
+#include "compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class RemoveSwitchFallThroughTraverser : public TIntermTraverser
+{
+ public:
+ static TIntermBlock *removeFallThrough(TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics);
+
+ private:
+ RemoveSwitchFallThroughTraverser(TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics);
+
+ void visitSymbol(TIntermSymbol *node) override;
+ void visitConstantUnion(TIntermConstantUnion *node) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ bool visitBinary(Visit, TIntermBinary *node) override;
+ bool visitUnary(Visit, TIntermUnary *node) override;
+ bool visitTernary(Visit visit, TIntermTernary *node) override;
+ bool visitSwizzle(Visit, TIntermSwizzle *node) override;
+ bool visitIfElse(Visit visit, TIntermIfElse *node) override;
+ bool visitSwitch(Visit, TIntermSwitch *node) override;
+ bool visitCase(Visit, TIntermCase *node) override;
+ bool visitAggregate(Visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit, TIntermBlock *node) override;
+ bool visitLoop(Visit, TIntermLoop *node) override;
+ bool visitBranch(Visit, TIntermBranch *node) override;
+
+ void outputSequence(TIntermSequence *sequence, size_t startIndex);
+ void handlePreviousCase();
+
+ TIntermBlock *mStatementList;
+ TIntermBlock *mStatementListOut;
+ bool mLastStatementWasBreak;
+ TIntermBlock *mPreviousCase;
+ std::vector<TIntermBlock *> mCasesSharingBreak;
+ PerformanceDiagnostics *mPerfDiagnostics;
+};
+
+TIntermBlock *RemoveSwitchFallThroughTraverser::removeFallThrough(
+ TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ RemoveSwitchFallThroughTraverser rm(statementList, perfDiagnostics);
+ ASSERT(statementList);
+ statementList->traverse(&rm);
+ ASSERT(rm.mPreviousCase || statementList->getSequence()->empty());
+ if (!rm.mLastStatementWasBreak && rm.mPreviousCase)
+ {
+ // Make sure that there's a branch at the end of the final case inside the switch statement.
+ // This also ensures that any cases that fall through to the final case will get the break.
+ TIntermBranch *finalBreak = new TIntermBranch(EOpBreak, nullptr);
+ rm.mPreviousCase->getSequence()->push_back(finalBreak);
+ rm.mLastStatementWasBreak = true;
+ }
+ rm.handlePreviousCase();
+ return rm.mStatementListOut;
+}
+
+RemoveSwitchFallThroughTraverser::RemoveSwitchFallThroughTraverser(
+ TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics)
+ : TIntermTraverser(true, false, false),
+ mStatementList(statementList),
+ mLastStatementWasBreak(false),
+ mPreviousCase(nullptr),
+ mPerfDiagnostics(perfDiagnostics)
+{
+ mStatementListOut = new TIntermBlock();
+}
+
+void RemoveSwitchFallThroughTraverser::visitSymbol(TIntermSymbol *node)
+{
+ // Note that this assumes that switch statements which don't begin by a case statement
+ // have already been weeded out in validation.
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+}
+
+void RemoveSwitchFallThroughTraverser::visitConstantUnion(TIntermConstantUnion *node)
+{
+ // Conditions of case labels are not traversed, so this is a constant statement like "0;".
+ // These are no-ops so there's no need to add them back to the statement list. Should have
+ // already been pruned out of the AST, in fact.
+ UNREACHABLE();
+}
+
+bool RemoveSwitchFallThroughTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitBinary(Visit, TIntermBinary *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitUnary(Visit, TIntermUnary *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitTernary(Visit, TIntermTernary *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitSwizzle(Visit, TIntermSwizzle *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitIfElse(Visit, TIntermIfElse *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitSwitch(Visit, TIntermSwitch *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ // Don't go into nested switch statements
+ return false;
+}
+
+void RemoveSwitchFallThroughTraverser::outputSequence(TIntermSequence *sequence, size_t startIndex)
+{
+ for (size_t i = startIndex; i < sequence->size(); ++i)
+ {
+ mStatementListOut->getSequence()->push_back(sequence->at(i));
+ }
+}
+
+void RemoveSwitchFallThroughTraverser::handlePreviousCase()
+{
+ if (mPreviousCase)
+ mCasesSharingBreak.push_back(mPreviousCase);
+ if (mLastStatementWasBreak)
+ {
+ for (size_t i = 0; i < mCasesSharingBreak.size(); ++i)
+ {
+ ASSERT(!mCasesSharingBreak.at(i)->getSequence()->empty());
+ if (mCasesSharingBreak.at(i)->getSequence()->size() == 1)
+ {
+ // Fall-through is allowed in case the label has no statements.
+ outputSequence(mCasesSharingBreak.at(i)->getSequence(), 0);
+ }
+ else
+ {
+ // Include all the statements that this case can fall through under the same label.
+ if (mCasesSharingBreak.size() > i + 1u)
+ {
+ mPerfDiagnostics->warning(mCasesSharingBreak.at(i)->getLine(),
+ "Performance: non-empty fall-through cases in "
+ "switch statements generate extra code.",
+ "switch");
+ }
+ for (size_t j = i; j < mCasesSharingBreak.size(); ++j)
+ {
+ size_t startIndex =
+ j > i ? 1 : 0; // Add the label only from the first sequence.
+ outputSequence(mCasesSharingBreak.at(j)->getSequence(), startIndex);
+ }
+ }
+ }
+ mCasesSharingBreak.clear();
+ }
+ mLastStatementWasBreak = false;
+ mPreviousCase = nullptr;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitCase(Visit, TIntermCase *node)
+{
+ handlePreviousCase();
+ mPreviousCase = new TIntermBlock();
+ mPreviousCase->getSequence()->push_back(node);
+ mPreviousCase->setLine(node->getLine());
+ // Don't traverse the condition of the case statement
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitAggregate(Visit, TIntermAggregate *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool DoesBlockAlwaysBreak(TIntermBlock *node)
+{
+ if (node->getSequence()->empty())
+ {
+ return false;
+ }
+
+ TIntermBlock *lastStatementAsBlock = node->getSequence()->back()->getAsBlock();
+ if (lastStatementAsBlock)
+ {
+ return DoesBlockAlwaysBreak(lastStatementAsBlock);
+ }
+
+ TIntermBranch *lastStatementAsBranch = node->getSequence()->back()->getAsBranchNode();
+ return lastStatementAsBranch != nullptr;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitBlock(Visit, TIntermBlock *node)
+{
+ if (node != mStatementList)
+ {
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = DoesBlockAlwaysBreak(node);
+ return false;
+ }
+ return true;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitLoop(Visit, TIntermLoop *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitBranch(Visit, TIntermBranch *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ // TODO: Verify that accepting return or continue statements here doesn't cause problems.
+ mLastStatementWasBreak = true;
+ return false;
+}
+
+} // anonymous namespace
+
+TIntermBlock *RemoveSwitchFallThrough(TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ return RemoveSwitchFallThroughTraverser::removeFallThrough(statementList, perfDiagnostics);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h
new file mode 100644
index 0000000000..b92e7e5f6d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RemoveSwitchFallThrough.h: Remove fall-through from switch statements.
+// Note that it is unsafe to do further AST transformations on the AST generated
+// by this function. It leaves duplicate nodes in the AST making replacements
+// unreliable.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_REMOVESWITCHFALLTHROUGH_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_REMOVESWITCHFALLTHROUGH_H_
+
+namespace sh
+{
+
+class TIntermBlock;
+class PerformanceDiagnostics;
+
+// When given a statementList from a switch AST node, return an updated
+// statementList that has fall-through removed.
+TIntermBlock *RemoveSwitchFallThrough(TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_REMOVESWITCHFALLTHROUGH_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.cpp
new file mode 100644
index 0000000000..b2de6079b7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.cpp
@@ -0,0 +1,183 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Implementation of the function RewriteAtomicFunctionExpressions.
+// See the header for more details.
+
+#include "compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h"
+
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+namespace
+{
+// Traverser that simplifies all the atomic function expressions into the ones that can be directly
+// translated into HLSL.
+//
+// case 1 (only for atomicExchange and atomicCompSwap):
+// original:
+// atomicExchange(counter, newValue);
+// new:
+// tempValue = atomicExchange(counter, newValue);
+//
+// case 2 (atomic function, temporary variable required):
+// original:
+// value = atomicAdd(counter, 1) * otherValue;
+// someArray[atomicAdd(counter, 1)] = someOtherValue;
+// new:
+// value = ((tempValue = atomicAdd(counter, 1)), tempValue) * otherValue;
+// someArray[((tempValue = atomicAdd(counter, 1)), tempValue)] = someOtherValue;
+//
+// case 3 (atomic function used directly initialize a variable):
+// original:
+// int value = atomicAdd(counter, 1);
+// new:
+// tempValue = atomicAdd(counter, 1);
+// int value = tempValue;
+//
+class RewriteAtomicFunctionExpressionsTraverser : public TIntermTraverser
+{
+ public:
+ RewriteAtomicFunctionExpressionsTraverser(TSymbolTable *symbolTable, int shaderVersion);
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+
+ private:
+ static bool IsAtomicExchangeOrCompSwapNoReturnValue(TIntermAggregate *node,
+ TIntermNode *parentNode);
+ static bool IsAtomicFunctionInsideExpression(TIntermAggregate *node, TIntermNode *parentNode);
+
+ void rewriteAtomicFunctionCallNode(TIntermAggregate *oldAtomicFunctionNode);
+
+ const TVariable *getTempVariable(const TType *type);
+
+ int mShaderVersion;
+ TIntermSequence mTempVariables;
+};
+
+RewriteAtomicFunctionExpressionsTraverser::RewriteAtomicFunctionExpressionsTraverser(
+ TSymbolTable *symbolTable,
+ int shaderVersion)
+ : TIntermTraverser(false, false, true, symbolTable), mShaderVersion(shaderVersion)
+{}
+
+void RewriteAtomicFunctionExpressionsTraverser::rewriteAtomicFunctionCallNode(
+ TIntermAggregate *oldAtomicFunctionNode)
+{
+ ASSERT(oldAtomicFunctionNode);
+
+ const TVariable *returnVariable = getTempVariable(&oldAtomicFunctionNode->getType());
+
+ TIntermBinary *rewrittenNode = new TIntermBinary(
+ TOperator::EOpAssign, CreateTempSymbolNode(returnVariable), oldAtomicFunctionNode);
+
+ auto *parentNode = getParentNode();
+
+ auto *parentBinary = parentNode->getAsBinaryNode();
+ if (parentBinary && parentBinary->getOp() == EOpInitialize)
+ {
+ insertStatementInParentBlock(rewrittenNode);
+ queueReplacement(CreateTempSymbolNode(returnVariable), OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ // As all atomic function assignment will be converted to the last argument of an
+ // interlocked function, if we need the return value, assignment needs to be wrapped with
+ // the comma operator and the temporary variables.
+ if (!parentNode->getAsBlock())
+ {
+ rewrittenNode = TIntermBinary::CreateComma(
+ rewrittenNode, new TIntermSymbol(returnVariable), mShaderVersion);
+ }
+
+ queueReplacement(rewrittenNode, OriginalNode::IS_DROPPED);
+ }
+}
+
+const TVariable *RewriteAtomicFunctionExpressionsTraverser::getTempVariable(const TType *type)
+{
+ TIntermDeclaration *variableDeclaration;
+ TVariable *returnVariable =
+ DeclareTempVariable(mSymbolTable, type, EvqTemporary, &variableDeclaration);
+ mTempVariables.push_back(variableDeclaration);
+ return returnVariable;
+}
+
+bool RewriteAtomicFunctionExpressionsTraverser::IsAtomicExchangeOrCompSwapNoReturnValue(
+ TIntermAggregate *node,
+ TIntermNode *parentNode)
+{
+ ASSERT(node);
+ return (node->getOp() == EOpAtomicExchange || node->getOp() == EOpAtomicCompSwap) &&
+ parentNode && parentNode->getAsBlock();
+}
+
+bool RewriteAtomicFunctionExpressionsTraverser::IsAtomicFunctionInsideExpression(
+ TIntermAggregate *node,
+ TIntermNode *parentNode)
+{
+ ASSERT(node);
+ // We only need to handle atomic functions with a parent that it is not block nodes. If the
+ // parent node is block, it means that the atomic function is not inside an expression.
+ if (!BuiltInGroup::IsAtomicMemory(node->getOp()) || parentNode->getAsBlock())
+ {
+ return false;
+ }
+
+ auto *parentAsBinary = parentNode->getAsBinaryNode();
+ // Assignments are handled in OutputHLSL
+ return !parentAsBinary || parentAsBinary->getOp() != EOpAssign;
+}
+
+bool RewriteAtomicFunctionExpressionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ ASSERT(visit == PostVisit);
+ // Skip atomic memory functions for SSBO. They will be processed in the OutputHLSL traverser.
+ if (BuiltInGroup::IsAtomicMemory(node->getOp()) &&
+ IsInShaderStorageBlock((*node->getSequence())[0]->getAsTyped()))
+ {
+ return false;
+ }
+
+ TIntermNode *parentNode = getParentNode();
+ if (IsAtomicExchangeOrCompSwapNoReturnValue(node, parentNode) ||
+ IsAtomicFunctionInsideExpression(node, parentNode))
+ {
+ rewriteAtomicFunctionCallNode(node);
+ }
+
+ return true;
+}
+
+bool RewriteAtomicFunctionExpressionsTraverser::visitBlock(Visit visit, TIntermBlock *node)
+{
+ ASSERT(visit == PostVisit);
+
+ if (!mTempVariables.empty() && getParentNode()->getAsFunctionDefinition())
+ {
+ insertStatementsInBlockAtPosition(node, 0, mTempVariables, TIntermSequence());
+ mTempVariables.clear();
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+bool RewriteAtomicFunctionExpressions(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ int shaderVersion)
+{
+ RewriteAtomicFunctionExpressionsTraverser traverser(symbolTable, shaderVersion);
+ traverser.traverse(root);
+ return traverser.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h
new file mode 100644
index 0000000000..60e6ffa2d1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h
@@ -0,0 +1,42 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteAtomicFunctionExpressions rewrites the expressions that contain
+// atomic function calls and cannot be directly translated into HLSL into
+// several simple ones that can be easily handled in the HLSL translator.
+//
+// We need to rewite these expressions because:
+// 1. All GLSL atomic functions have return values, which all represent the
+// original value of the shared or ssbo variable; while all HLSL atomic
+// functions don't, and the original value can be stored in the last
+// parameter of the function call.
+// 2. For HLSL atomic functions, the last parameter that stores the original
+// value is optional except for InterlockedExchange and
+// InterlockedCompareExchange. Missing original_value in the call of
+// InterlockedExchange or InterlockedCompareExchange results in a compile
+// error from HLSL compiler.
+//
+// RewriteAtomicFunctionExpressions is a function that can modify the AST
+// to ensure all the expressions that contain atomic function calls can be
+// directly translated into HLSL expressions.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_ATOMIC_FUNCTION_EXPRESSIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_ATOMIC_FUNCTION_EXPRESSIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteAtomicFunctionExpressions(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ int shaderVersion);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_ATOMIC_FUNCTION_EXPRESSIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.cpp
new file mode 100644
index 0000000000..10647d1bf1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.cpp
@@ -0,0 +1,123 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteElseBlocks.cpp: Implementation for tree transform to change
+// all if-else blocks to if-if blocks.
+//
+
+#include "compiler/translator/tree_ops/d3d/RewriteElseBlocks.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/NodeSearch.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class ElseBlockRewriter : public TIntermTraverser
+{
+ public:
+ ElseBlockRewriter(TSymbolTable *symbolTable);
+
+ protected:
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *aggregate) override;
+ bool visitBlock(Visit visit, TIntermBlock *block) override;
+
+ private:
+ TIntermNode *rewriteIfElse(TIntermIfElse *ifElse);
+
+ const TType *mFunctionType;
+};
+
+ElseBlockRewriter::ElseBlockRewriter(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, true, symbolTable), mFunctionType(nullptr)
+{}
+
+bool ElseBlockRewriter::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+{
+ // Store the current function context (see comment below)
+ mFunctionType = ((visit == PreVisit) ? &node->getFunctionPrototype()->getType() : nullptr);
+ return true;
+}
+
+bool ElseBlockRewriter::visitBlock(Visit visit, TIntermBlock *node)
+{
+ if (visit == PostVisit)
+ {
+ for (size_t statementIndex = 0; statementIndex != node->getSequence()->size();
+ statementIndex++)
+ {
+ TIntermNode *statement = (*node->getSequence())[statementIndex];
+ TIntermIfElse *ifElse = statement->getAsIfElseNode();
+ if (ifElse && ifElse->getFalseBlock() != nullptr)
+ {
+ (*node->getSequence())[statementIndex] = rewriteIfElse(ifElse);
+ }
+ }
+ }
+ return true;
+}
+
+TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse)
+{
+ ASSERT(ifElse != nullptr);
+
+ TIntermDeclaration *storeCondition = nullptr;
+ TVariable *conditionVariable =
+ DeclareTempVariable(mSymbolTable, ifElse->getCondition(), EvqTemporary, &storeCondition);
+
+ TIntermBlock *falseBlock = nullptr;
+
+ TType boolType(EbtBool, EbpUndefined, EvqTemporary);
+
+ if (ifElse->getFalseBlock())
+ {
+ TIntermBlock *negatedElse = nullptr;
+ // crbug.com/346463
+ // D3D generates error messages claiming a function has no return value, when rewriting
+ // an if-else clause that returns something non-void in a function. By appending mock
+ // returns (that are unreachable) we can silence this compile error.
+ if (mFunctionType && mFunctionType->getBasicType() != EbtVoid)
+ {
+ TIntermNode *returnNode = new TIntermBranch(EOpReturn, CreateZeroNode(*mFunctionType));
+ negatedElse = new TIntermBlock();
+ negatedElse->appendStatement(returnNode);
+ }
+
+ TIntermSymbol *conditionSymbolElse = CreateTempSymbolNode(conditionVariable);
+ TIntermUnary *negatedCondition =
+ new TIntermUnary(EOpLogicalNot, conditionSymbolElse, nullptr);
+ TIntermIfElse *falseIfElse =
+ new TIntermIfElse(negatedCondition, ifElse->getFalseBlock(), negatedElse);
+ falseBlock = EnsureBlock(falseIfElse);
+ }
+
+ TIntermSymbol *conditionSymbolSel = CreateTempSymbolNode(conditionVariable);
+ TIntermIfElse *newIfElse =
+ new TIntermIfElse(conditionSymbolSel, ifElse->getTrueBlock(), falseBlock);
+
+ TIntermBlock *block = new TIntermBlock();
+ block->getSequence()->push_back(storeCondition);
+ block->getSequence()->push_back(newIfElse);
+
+ return block;
+}
+
+} // anonymous namespace
+
+bool RewriteElseBlocks(TCompiler *compiler, TIntermNode *node, TSymbolTable *symbolTable)
+{
+ ElseBlockRewriter rewriter(symbolTable);
+ node->traverse(&rewriter);
+
+ return compiler->validateAST(node);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.h
new file mode 100644
index 0000000000..cab0f7090c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteElseBlocks.h: Prototype for tree transform to change
+// all if-else blocks to if-if blocks.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITEELSEBLOCKS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITEELSEBLOCKS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteElseBlocks(TCompiler *compiler,
+ TIntermNode *node,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITEELSEBLOCKS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.cpp
new file mode 100644
index 0000000000..709f394878
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.cpp
@@ -0,0 +1,420 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteExpressionsWithShaderStorageBlock rewrites the expressions that contain shader storage
+// block calls into several simple ones that can be easily handled in the HLSL translator. After the
+// AST pass, all ssbo related blocks will be like below:
+// ssbo_access_chain = ssbo_access_chain;
+// ssbo_access_chain = expr_no_ssbo;
+// lvalue_no_ssbo = ssbo_access_chain;
+//
+
+#include "compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h"
+
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+namespace
+{
+
+bool IsIncrementOrDecrementOperator(TOperator op)
+{
+ switch (op)
+ {
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsCompoundAssignment(TOperator op)
+{
+ switch (op)
+ {
+ case EOpAddAssign:
+ case EOpSubAssign:
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+ case EOpDivAssign:
+ case EOpIModAssign:
+ case EOpBitShiftLeftAssign:
+ case EOpBitShiftRightAssign:
+ case EOpBitwiseAndAssign:
+ case EOpBitwiseXorAssign:
+ case EOpBitwiseOrAssign:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// EOpIndexDirect, EOpIndexIndirect, EOpIndexDirectStruct, EOpIndexDirectInterfaceBlock belong to
+// operators in SSBO access chain.
+bool IsReadonlyBinaryOperatorNotInSSBOAccessChain(TOperator op)
+{
+ switch (op)
+ {
+ case EOpComma:
+ case EOpAdd:
+ case EOpSub:
+ case EOpMul:
+ case EOpDiv:
+ case EOpIMod:
+ case EOpBitShiftLeft:
+ case EOpBitShiftRight:
+ case EOpBitwiseAnd:
+ case EOpBitwiseXor:
+ case EOpBitwiseOr:
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ case EOpVectorTimesScalar:
+ case EOpMatrixTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesMatrix:
+ case EOpLogicalOr:
+ case EOpLogicalXor:
+ case EOpLogicalAnd:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool HasSSBOAsFunctionArgument(TIntermSequence *arguments)
+{
+ for (TIntermNode *arg : *arguments)
+ {
+ TIntermTyped *typedArg = arg->getAsTyped();
+ if (IsInShaderStorageBlock(typedArg))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+class RewriteExpressionsWithShaderStorageBlockTraverser : public TIntermTraverser
+{
+ public:
+ RewriteExpressionsWithShaderStorageBlockTraverser(TSymbolTable *symbolTable);
+ void nextIteration();
+ bool foundSSBO() const { return mFoundSSBO; }
+
+ private:
+ bool visitBinary(Visit, TIntermBinary *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+
+ TIntermSymbol *insertInitStatementAndReturnTempSymbol(TIntermTyped *node,
+ TIntermSequence *insertions);
+
+ bool mFoundSSBO;
+};
+
+RewriteExpressionsWithShaderStorageBlockTraverser::
+ RewriteExpressionsWithShaderStorageBlockTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, true, false, symbolTable), mFoundSSBO(false)
+{}
+
+TIntermSymbol *
+RewriteExpressionsWithShaderStorageBlockTraverser::insertInitStatementAndReturnTempSymbol(
+ TIntermTyped *node,
+ TIntermSequence *insertions)
+{
+ TIntermDeclaration *variableDeclaration;
+ TVariable *tempVariable =
+ DeclareTempVariable(mSymbolTable, node, EvqTemporary, &variableDeclaration);
+
+ insertions->push_back(variableDeclaration);
+ return CreateTempSymbolNode(tempVariable);
+}
+
+bool RewriteExpressionsWithShaderStorageBlockTraverser::visitBinary(Visit visit,
+ TIntermBinary *node)
+{
+ // Make sure that the expression is caculated from left to right.
+ if (visit != InVisit)
+ {
+ return true;
+ }
+
+ if (mFoundSSBO)
+ {
+ return false;
+ }
+
+ bool rightSSBO = IsInShaderStorageBlock(node->getRight());
+ bool leftSSBO = IsInShaderStorageBlock(node->getLeft());
+ if (!leftSSBO && !rightSSBO)
+ {
+ return true;
+ }
+
+ // case 1: Compound assigment operator
+ // original:
+ // lssbo += expr;
+ // new:
+ // var rvalue = expr;
+ // var temp = lssbo;
+ // temp += rvalue;
+ // lssbo = temp;
+ //
+ // original:
+ // lvalue_no_ssbo += rssbo;
+ // new:
+ // var rvalue = rssbo;
+ // lvalue_no_ssbo += rvalue;
+ if (IsCompoundAssignment(node->getOp()))
+ {
+ mFoundSSBO = true;
+ TIntermSequence insertions;
+ TIntermTyped *rightNode =
+ insertInitStatementAndReturnTempSymbol(node->getRight(), &insertions);
+ if (leftSSBO)
+ {
+ TIntermSymbol *tempSymbol =
+ insertInitStatementAndReturnTempSymbol(node->getLeft()->deepCopy(), &insertions);
+ TIntermBinary *tempCompoundOperate =
+ new TIntermBinary(node->getOp(), tempSymbol->deepCopy(), rightNode->deepCopy());
+ insertions.push_back(tempCompoundOperate);
+ insertStatementsInParentBlock(insertions);
+
+ TIntermBinary *assignTempValueToSSBO =
+ new TIntermBinary(EOpAssign, node->getLeft(), tempSymbol->deepCopy());
+ queueReplacement(assignTempValueToSSBO, OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ insertStatementsInParentBlock(insertions);
+ TIntermBinary *compoundAssignRValueToLValue =
+ new TIntermBinary(node->getOp(), node->getLeft(), rightNode->deepCopy());
+ queueReplacement(compoundAssignRValueToLValue, OriginalNode::IS_DROPPED);
+ }
+ }
+ // case 2: Readonly binary operator
+ // original:
+ // ssbo0 + ssbo1 + ssbo2;
+ // new:
+ // var temp0 = ssbo0;
+ // var temp1 = ssbo1;
+ // var temp2 = ssbo2;
+ // temp0 + temp1 + temp2;
+ else if (IsReadonlyBinaryOperatorNotInSSBOAccessChain(node->getOp()) && (leftSSBO || rightSSBO))
+ {
+ mFoundSSBO = true;
+ TIntermTyped *rightNode = node->getRight();
+ TIntermTyped *leftNode = node->getLeft();
+ TIntermSequence insertions;
+ if (rightSSBO)
+ {
+ rightNode = insertInitStatementAndReturnTempSymbol(node->getRight(), &insertions);
+ }
+ if (leftSSBO)
+ {
+ leftNode = insertInitStatementAndReturnTempSymbol(node->getLeft(), &insertions);
+ }
+
+ insertStatementsInParentBlock(insertions);
+ TIntermBinary *newExpr =
+ new TIntermBinary(node->getOp(), leftNode->deepCopy(), rightNode->deepCopy());
+ queueReplacement(newExpr, OriginalNode::IS_DROPPED);
+ }
+ return !mFoundSSBO;
+}
+
+// case 3: ssbo as the argument of aggregate type
+// original:
+// foo(ssbo);
+// new:
+// var tempArg = ssbo;
+// foo(tempArg);
+// ssbo = tempArg; (Optional based on whether ssbo is an out|input argument)
+//
+// original:
+// foo(ssbo) * expr;
+// new:
+// var tempArg = ssbo;
+// var tempReturn = foo(tempArg);
+// ssbo = tempArg; (Optional based on whether ssbo is an out|input argument)
+// tempReturn * expr;
+bool RewriteExpressionsWithShaderStorageBlockTraverser::visitAggregate(Visit visit,
+ TIntermAggregate *node)
+{
+ // Make sure that visitAggregate is only executed once for same node.
+ if (visit != PreVisit)
+ {
+ return true;
+ }
+
+ if (mFoundSSBO)
+ {
+ return false;
+ }
+
+ // We still need to process the ssbo as the non-first argument of atomic memory functions.
+ if (BuiltInGroup::IsAtomicMemory(node->getOp()) &&
+ IsInShaderStorageBlock((*node->getSequence())[0]->getAsTyped()))
+ {
+ return true;
+ }
+
+ if (!HasSSBOAsFunctionArgument(node->getSequence()))
+ {
+ return true;
+ }
+
+ mFoundSSBO = true;
+ TIntermSequence insertions;
+ TIntermSequence readBackToSSBOs;
+ TIntermSequence *originalArguments = node->getSequence();
+ for (size_t i = 0; i < node->getChildCount(); ++i)
+ {
+ TIntermTyped *ssboArgument = (*originalArguments)[i]->getAsTyped();
+ if (IsInShaderStorageBlock(ssboArgument))
+ {
+ TIntermSymbol *argumentCopy =
+ insertInitStatementAndReturnTempSymbol(ssboArgument, &insertions);
+ if (node->getFunction() != nullptr)
+ {
+ TQualifier qual = node->getFunction()->getParam(i)->getType().getQualifier();
+ if (qual == EvqParamInOut || qual == EvqParamOut)
+ {
+ TIntermBinary *readBackToSSBO = new TIntermBinary(
+ EOpAssign, ssboArgument->deepCopy(), argumentCopy->deepCopy());
+ readBackToSSBOs.push_back(readBackToSSBO);
+ }
+ }
+ node->replaceChildNode(ssboArgument, argumentCopy);
+ }
+ }
+
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ if (parentBlock)
+ {
+ // Aggregate node is as a single sentence.
+ insertions.push_back(node);
+ if (!readBackToSSBOs.empty())
+ {
+ insertions.insert(insertions.end(), readBackToSSBOs.begin(), readBackToSSBOs.end());
+ }
+ mMultiReplacements.emplace_back(parentBlock, node, std::move(insertions));
+ }
+ else
+ {
+ // Aggregate node is inside an expression.
+ TIntermSymbol *tempSymbol = insertInitStatementAndReturnTempSymbol(node, &insertions);
+ if (!readBackToSSBOs.empty())
+ {
+ insertions.insert(insertions.end(), readBackToSSBOs.begin(), readBackToSSBOs.end());
+ }
+ insertStatementsInParentBlock(insertions);
+ queueReplacement(tempSymbol->deepCopy(), OriginalNode::IS_DROPPED);
+ }
+
+ return false;
+}
+
+bool RewriteExpressionsWithShaderStorageBlockTraverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ if (mFoundSSBO)
+ {
+ return false;
+ }
+
+ if (!IsInShaderStorageBlock(node->getOperand()))
+ {
+ return true;
+ }
+
+ // .length() is processed in OutputHLSL.
+ if (node->getOp() == EOpArrayLength)
+ {
+ return true;
+ }
+
+ mFoundSSBO = true;
+
+ // case 4: ssbo as the operand of ++/--
+ // original:
+ // ++ssbo * expr;
+ // new:
+ // var temp1 = ssbo;
+ // var temp2 = ++temp1;
+ // ssbo = temp1;
+ // temp2 * expr;
+ if (IsIncrementOrDecrementOperator(node->getOp()))
+ {
+ TIntermSequence insertions;
+ TIntermSymbol *temp1 =
+ insertInitStatementAndReturnTempSymbol(node->getOperand(), &insertions);
+ TIntermUnary *newUnary = new TIntermUnary(node->getOp(), temp1->deepCopy(), nullptr);
+ TIntermSymbol *temp2 = insertInitStatementAndReturnTempSymbol(newUnary, &insertions);
+ TIntermBinary *readBackToSSBO =
+ new TIntermBinary(EOpAssign, node->getOperand()->deepCopy(), temp1->deepCopy());
+ insertions.push_back(readBackToSSBO);
+ insertStatementsInParentBlock(insertions);
+ queueReplacement(temp2->deepCopy(), OriginalNode::IS_DROPPED);
+ }
+ // case 5: ssbo as the operand of readonly unary operator
+ // original:
+ // ~ssbo * expr;
+ // new:
+ // var temp = ssbo;
+ // ~temp * expr;
+ else
+ {
+ TIntermSequence insertions;
+ TIntermSymbol *temp =
+ insertInitStatementAndReturnTempSymbol(node->getOperand(), &insertions);
+ insertStatementsInParentBlock(insertions);
+ node->replaceChildNode(node->getOperand(), temp->deepCopy());
+ }
+ return false;
+}
+
+void RewriteExpressionsWithShaderStorageBlockTraverser::nextIteration()
+{
+ mFoundSSBO = false;
+}
+
+} // anonymous namespace
+
+bool RewriteExpressionsWithShaderStorageBlock(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ RewriteExpressionsWithShaderStorageBlockTraverser traverser(symbolTable);
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.foundSSBO())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.foundSSBO());
+
+ return true;
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h
new file mode 100644
index 0000000000..bf824c4a23
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h
@@ -0,0 +1,37 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteExpressionsWithShaderStorageBlock rewrites the expressions that contain shader storage
+// block calls into several simple ones that can be easily handled in the HLSL translator. After the
+// AST pass, all ssbo related blocks will be like below:
+// ssbo_access_chain = ssbo_access_chain;
+// ssbo_access_chain = expr_no_ssbo;
+// lvalue_no_ssbo = ssbo_access_chain;
+//
+// Below situations are needed to be rewritten (Details can be found in .cpp file).
+// SSBO as the operand of compound assignment operators.
+// SSBO as the operand of ++/--.
+// SSBO as the operand of repeated assignment.
+// SSBO as the operand of readonly unary/binary/ternary operators.
+// SSBO as the argument of aggregate type.
+// SSBO as the condition of if/switch/while/do-while/for
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_EXPRESSIONS_WITH_SHADER_STORAGE_BLOCK_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_EXPRESSIONS_WITH_SHADER_STORAGE_BLOCK_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteExpressionsWithShaderStorageBlock(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_EXPRESSIONS_WITH_SHADER_STORAGE_BLOCK_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.cpp
new file mode 100644
index 0000000000..5d8cdb657d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.cpp
@@ -0,0 +1,117 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Implementation of evaluating unary integer variable bug workaround.
+// See header for more info.
+
+#include "compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h"
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class Traverser : public TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool Apply(TCompiler *compiler, TIntermNode *root);
+
+ private:
+ Traverser();
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+ void nextIteration();
+
+ bool mFound = false;
+};
+
+// static
+bool Traverser::Apply(TCompiler *compiler, TIntermNode *root)
+{
+ Traverser traverser;
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.mFound)
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.mFound);
+
+ return true;
+}
+
+Traverser::Traverser() : TIntermTraverser(true, false, false) {}
+
+void Traverser::nextIteration()
+{
+ mFound = false;
+}
+
+bool Traverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ if (mFound)
+ {
+ return false;
+ }
+
+ // Decide if the current unary operator is unary minus.
+ if (node->getOp() != EOpNegative)
+ {
+ return true;
+ }
+
+ // Decide if the current operand is an integer variable.
+ TIntermTyped *opr = node->getOperand();
+ if (!opr->getType().isScalarInt())
+ {
+ return true;
+ }
+
+ // Potential problem case detected, apply workaround: -(int) -> ~(int) + 1.
+ // ~(int)
+ TIntermUnary *bitwiseNot = new TIntermUnary(EOpBitwiseNot, opr, nullptr);
+ bitwiseNot->setLine(opr->getLine());
+
+ // Constant 1 (or 1u)
+ TConstantUnion *one = new TConstantUnion();
+ if (opr->getType().getBasicType() == EbtInt)
+ {
+ one->setIConst(1);
+ }
+ else
+ {
+ one->setUConst(1u);
+ }
+ TType *oneType = new TType(opr->getType());
+ oneType->setQualifier(EvqConst);
+
+ TIntermConstantUnion *oneNode = new TIntermConstantUnion(one, *oneType);
+ oneNode->setLine(opr->getLine());
+
+ // ~(int) + 1
+ TIntermBinary *add = new TIntermBinary(EOpAdd, bitwiseNot, oneNode);
+ add->setLine(opr->getLine());
+
+ queueReplacement(add, OriginalNode::IS_DROPPED);
+
+ mFound = true;
+ return false;
+}
+
+} // anonymous namespace
+
+bool RewriteUnaryMinusOperatorInt(TCompiler *compiler, TIntermNode *root)
+{
+ return Traverser::Apply(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h
new file mode 100644
index 0000000000..cc5ac86456
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h
@@ -0,0 +1,23 @@
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This mutating tree traversal works around a bug on evaluating unary
+// integer variable on Intel D3D driver. It works by rewriting -(int) to
+// ~(int) + 1 when evaluating unary integer variables.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITEUNARYMINUSOPERATORINT_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITEUNARYMINUSOPERATORINT_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+[[nodiscard]] bool RewriteUnaryMinusOperatorInt(TCompiler *compiler, TIntermNode *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITEUNARYMINUSOPERATORINT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.cpp
new file mode 100644
index 0000000000..170b29acd7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.cpp
@@ -0,0 +1,83 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SeparateArrayConstructorStatements splits statements that are array constructors and drops all of
+// their constant arguments. For example, a statement like:
+// int[2](0, i++);
+// Will be changed to:
+// i++;
+
+#include "compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h"
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void SplitConstructorArgs(const TIntermSequence &originalArgs, TIntermSequence *argsOut)
+{
+ for (TIntermNode *arg : originalArgs)
+ {
+ TIntermTyped *argTyped = arg->getAsTyped();
+ if (argTyped->hasSideEffects())
+ {
+ TIntermAggregate *argAggregate = argTyped->getAsAggregate();
+ if (argTyped->isArray() && argAggregate && argAggregate->isConstructor())
+ {
+ SplitConstructorArgs(*argAggregate->getSequence(), argsOut);
+ }
+ else
+ {
+ argsOut->push_back(argTyped);
+ }
+ }
+ }
+}
+
+class SeparateArrayConstructorStatementsTraverser : public TIntermTraverser
+{
+ public:
+ SeparateArrayConstructorStatementsTraverser();
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+};
+
+SeparateArrayConstructorStatementsTraverser::SeparateArrayConstructorStatementsTraverser()
+ : TIntermTraverser(true, false, false)
+{}
+
+bool SeparateArrayConstructorStatementsTraverser::visitAggregate(Visit visit,
+ TIntermAggregate *node)
+{
+ TIntermBlock *parentAsBlock = getParentNode()->getAsBlock();
+ if (!parentAsBlock)
+ {
+ return false;
+ }
+ if (!node->isArray() || !node->isConstructor())
+ {
+ return false;
+ }
+
+ TIntermSequence constructorArgs;
+ SplitConstructorArgs(*node->getSequence(), &constructorArgs);
+ mMultiReplacements.emplace_back(parentAsBlock, node, std::move(constructorArgs));
+
+ return false;
+}
+
+} // namespace
+
+bool SeparateArrayConstructorStatements(TCompiler *compiler, TIntermBlock *root)
+{
+ SeparateArrayConstructorStatementsTraverser traverser;
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h
new file mode 100644
index 0000000000..225a4651da
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SeparateArrayConstructorStatements splits statements that are array constructors and drops all of
+// their constant arguments. For example, a statement like:
+// int[2](0, i++);
+// Will be changed to:
+// i++;
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+
+[[nodiscard]] bool SeparateArrayConstructorStatements(TCompiler *compiler, TIntermBlock *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.cpp
new file mode 100644
index 0000000000..de5c393cf6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.cpp
@@ -0,0 +1,89 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The SeparateArrayInitialization function splits each array initialization into a declaration and
+// an assignment.
+// Example:
+// type[n] a = initializer;
+// will effectively become
+// type[n] a;
+// a = initializer;
+//
+// Note that if the array is declared as const, the initialization may still be split, making the
+// AST technically invalid. Because of that this transformation should only be used when subsequent
+// stages don't care about const qualifiers. However, the initialization will not be split if the
+// initializer can be written as a HLSL literal.
+
+#include "compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/OutputHLSL.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class SeparateArrayInitTraverser : private TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool apply(TCompiler *compiler, TIntermNode *root);
+
+ private:
+ SeparateArrayInitTraverser();
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+};
+
+bool SeparateArrayInitTraverser::apply(TCompiler *compiler, TIntermNode *root)
+{
+ SeparateArrayInitTraverser separateInit;
+ root->traverse(&separateInit);
+ return separateInit.updateTree(compiler, root);
+}
+
+SeparateArrayInitTraverser::SeparateArrayInitTraverser() : TIntermTraverser(true, false, false) {}
+
+bool SeparateArrayInitTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ TIntermSequence *sequence = node->getSequence();
+ TIntermBinary *initNode = sequence->back()->getAsBinaryNode();
+ if (initNode != nullptr && initNode->getOp() == EOpInitialize)
+ {
+ TIntermTyped *initializer = initNode->getRight();
+ if (initializer->isArray() && !initializer->hasConstantValue())
+ {
+ // We rely on that array declarations have been isolated to single declarations.
+ ASSERT(sequence->size() == 1);
+ TIntermTyped *symbol = initNode->getLeft();
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ ASSERT(parentBlock != nullptr);
+
+ TIntermSequence replacements;
+
+ TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
+ replacementDeclaration->appendDeclarator(symbol);
+ replacementDeclaration->setLine(symbol->getLine());
+ replacements.push_back(replacementDeclaration);
+
+ TIntermBinary *replacementAssignment =
+ new TIntermBinary(EOpAssign, symbol, initializer);
+ replacementAssignment->setLine(symbol->getLine());
+ replacements.push_back(replacementAssignment);
+
+ mMultiReplacements.emplace_back(parentBlock, node, std::move(replacements));
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+bool SeparateArrayInitialization(TCompiler *compiler, TIntermNode *root)
+{
+ return SeparateArrayInitTraverser::apply(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h
new file mode 100644
index 0000000000..e83554186a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The SeparateArrayInitialization function splits each array initialization into a declaration and
+// an assignment.
+// Example:
+// type[n] a = initializer;
+// will effectively become
+// type[n] a;
+// a = initializer;
+//
+// Note that if the array is declared as const, the initialization may still be split, making the
+// AST technically invalid. Because of that this transformation should only be used when subsequent
+// stages don't care about const qualifiers. However, the initialization will not be split if the
+// initializer can be written as a HLSL literal.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYINITIALIZATION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYINITIALIZATION_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+[[nodiscard]] bool SeparateArrayInitialization(TCompiler *compiler, TIntermNode *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYINITIALIZATION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.cpp
new file mode 100644
index 0000000000..58d8a0a9be
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.cpp
@@ -0,0 +1,138 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names
+// from more complex expressions, assigning them to a temporary variable a#.
+// Examples where a, b and c are all arrays:
+// (a = b) == (a = c) is split into a = b; type[n] a1 = a; a = c; type[n] a2 = a; a1 == a2;
+// type d = type[n](...)[i]; is split into type[n] a1 = type[n](...); type d = a1[i];
+
+#include "compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h"
+
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Traverser that separates one array expression into a statement at a time.
+class SeparateExpressionsTraverser : public TIntermTraverser
+{
+ public:
+ SeparateExpressionsTraverser(TSymbolTable *symbolTable);
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+ void nextIteration();
+ bool foundArrayExpression() const { return mFoundArrayExpression; }
+
+ protected:
+ // Marked to true once an operation that needs to be hoisted out of the expression has been
+ // found. After that, no more AST updates are performed on that traversal.
+ bool mFoundArrayExpression;
+
+ IntermNodePatternMatcher mPatternToSeparateMatcher;
+};
+
+SeparateExpressionsTraverser::SeparateExpressionsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mFoundArrayExpression(false),
+ mPatternToSeparateMatcher(IntermNodePatternMatcher::kExpressionReturningArray)
+{}
+
+// Performs a shallow copy of an assignment node.
+// These shallow copies are useful when a node gets inserted into an aggregate node
+// and also needs to be replaced in its original location by a different node.
+TIntermBinary *CopyAssignmentNode(TIntermBinary *node)
+{
+ return new TIntermBinary(node->getOp(), node->getLeft(), node->getRight());
+}
+
+bool SeparateExpressionsTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (mFoundArrayExpression)
+ return false;
+
+ // Return if the expression is not an array or if we're not inside a complex expression.
+ if (!mPatternToSeparateMatcher.match(node, getParentNode()))
+ return true;
+
+ ASSERT(node->getOp() == EOpAssign);
+
+ mFoundArrayExpression = true;
+
+ TIntermSequence insertions;
+ insertions.push_back(CopyAssignmentNode(node));
+ // TODO(oetuaho): In some cases it would be more optimal to not add the temporary node, but just
+ // use the original target of the assignment. Care must be taken so that this doesn't happen
+ // when the same array symbol is a target of assignment more than once in one expression.
+ TIntermDeclaration *arrayVariableDeclaration;
+ TVariable *arrayVariable =
+ DeclareTempVariable(mSymbolTable, node->getLeft(), EvqTemporary, &arrayVariableDeclaration);
+ insertions.push_back(arrayVariableDeclaration);
+ insertStatementsInParentBlock(insertions);
+
+ queueReplacement(CreateTempSymbolNode(arrayVariable), OriginalNode::IS_DROPPED);
+
+ return false;
+}
+
+bool SeparateExpressionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ if (mFoundArrayExpression)
+ return false; // No need to traverse further
+
+ if (!mPatternToSeparateMatcher.match(node, getParentNode()))
+ return true;
+
+ ASSERT(node->isConstructor() || node->getOp() == EOpCallFunctionInAST);
+
+ mFoundArrayExpression = true;
+
+ TIntermDeclaration *arrayVariableDeclaration;
+ TVariable *arrayVariable = DeclareTempVariable(mSymbolTable, node->shallowCopy(), EvqTemporary,
+ &arrayVariableDeclaration);
+ insertStatementInParentBlock(arrayVariableDeclaration);
+
+ queueReplacement(CreateTempSymbolNode(arrayVariable), OriginalNode::IS_DROPPED);
+
+ return false;
+}
+
+void SeparateExpressionsTraverser::nextIteration()
+{
+ mFoundArrayExpression = false;
+}
+
+} // namespace
+
+bool SeparateExpressionsReturningArrays(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ SeparateExpressionsTraverser traverser(symbolTable);
+ // Separate one expression at a time, and reset the traverser between iterations.
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.foundArrayExpression())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.foundArrayExpression());
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h
new file mode 100644
index 0000000000..6a9350d89a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names
+// from more complex expressions, assigning them to a temporary variable a#.
+// Examples where a, b and c are all arrays:
+// (a = b) == (a = c) is split into a = b; type[n] a1 = a; a = c; type[n] a2 = a; a1 == a2;
+// type d = type[n](...)[i]; is split into type[n] a1 = type[n](...); type d = a1[i];
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool SeparateExpressionsReturningArrays(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.cpp
new file mode 100644
index 0000000000..5b104c4889
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.cpp
@@ -0,0 +1,200 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// UnfoldShortCircuitToIf is an AST traverser to convert short-circuiting operators to if-else
+// statements.
+// The results are assigned to s# temporaries, which are used by the main translator instead of
+// the original expression.
+//
+
+#include "compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h"
+
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Traverser that unfolds one short-circuiting operation at a time.
+class UnfoldShortCircuitTraverser : public TIntermTraverser
+{
+ public:
+ UnfoldShortCircuitTraverser(TSymbolTable *symbolTable);
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ bool visitTernary(Visit visit, TIntermTernary *node) override;
+
+ void nextIteration();
+ bool foundShortCircuit() const { return mFoundShortCircuit; }
+
+ protected:
+ // Marked to true once an operation that needs to be unfolded has been found.
+ // After that, no more unfolding is performed on that traversal.
+ bool mFoundShortCircuit;
+
+ IntermNodePatternMatcher mPatternToUnfoldMatcher;
+};
+
+UnfoldShortCircuitTraverser::UnfoldShortCircuitTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, true, symbolTable),
+ mFoundShortCircuit(false),
+ mPatternToUnfoldMatcher(IntermNodePatternMatcher::kUnfoldedShortCircuitExpression)
+{}
+
+bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (mFoundShortCircuit)
+ return false;
+
+ if (visit != PreVisit)
+ return true;
+
+ if (!mPatternToUnfoldMatcher.match(node, getParentNode()))
+ return true;
+
+ // If our right node doesn't have side effects, we know we don't need to unfold this
+ // expression: there will be no short-circuiting side effects to avoid
+ // (note: unfolding doesn't depend on the left node -- it will always be evaluated)
+ ASSERT(node->getRight()->hasSideEffects());
+
+ mFoundShortCircuit = true;
+
+ switch (node->getOp())
+ {
+ case EOpLogicalOr:
+ {
+ // "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true;
+ // else s = y;",
+ // and then further simplifies down to "bool s = x; if(!s) s = y;".
+
+ TIntermSequence insertions;
+ const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
+ TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
+
+ ASSERT(node->getLeft()->getType() == *boolType);
+ insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
+
+ TIntermBlock *assignRightBlock = new TIntermBlock();
+ ASSERT(node->getRight()->getType() == *boolType);
+ assignRightBlock->getSequence()->push_back(
+ CreateTempAssignmentNode(resultVariable, node->getRight()));
+
+ TIntermUnary *notTempSymbol =
+ new TIntermUnary(EOpLogicalNot, CreateTempSymbolNode(resultVariable), nullptr);
+ TIntermIfElse *ifNode = new TIntermIfElse(notTempSymbol, assignRightBlock, nullptr);
+ insertions.push_back(ifNode);
+
+ insertStatementsInParentBlock(insertions);
+
+ queueReplacement(CreateTempSymbolNode(resultVariable), OriginalNode::IS_DROPPED);
+ return false;
+ }
+ case EOpLogicalAnd:
+ {
+ // "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y;
+ // else s = false;",
+ // and then further simplifies down to "bool s = x; if(s) s = y;".
+ TIntermSequence insertions;
+ const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
+ TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
+
+ ASSERT(node->getLeft()->getType() == *boolType);
+ insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
+
+ TIntermBlock *assignRightBlock = new TIntermBlock();
+ ASSERT(node->getRight()->getType() == *boolType);
+ assignRightBlock->getSequence()->push_back(
+ CreateTempAssignmentNode(resultVariable, node->getRight()));
+
+ TIntermIfElse *ifNode =
+ new TIntermIfElse(CreateTempSymbolNode(resultVariable), assignRightBlock, nullptr);
+ insertions.push_back(ifNode);
+
+ insertStatementsInParentBlock(insertions);
+
+ queueReplacement(CreateTempSymbolNode(resultVariable), OriginalNode::IS_DROPPED);
+ return false;
+ }
+ default:
+ UNREACHABLE();
+ return true;
+ }
+}
+
+bool UnfoldShortCircuitTraverser::visitTernary(Visit visit, TIntermTernary *node)
+{
+ if (mFoundShortCircuit)
+ return false;
+
+ if (visit != PreVisit)
+ return true;
+
+ if (!mPatternToUnfoldMatcher.match(node))
+ return true;
+
+ mFoundShortCircuit = true;
+
+ // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;"
+ TIntermSequence insertions;
+ TIntermDeclaration *tempDeclaration = nullptr;
+ TVariable *resultVariable = DeclareTempVariable(mSymbolTable, new TType(node->getType()),
+ EvqTemporary, &tempDeclaration);
+ insertions.push_back(tempDeclaration);
+
+ TIntermBlock *trueBlock = new TIntermBlock();
+ TIntermBinary *trueAssignment =
+ CreateTempAssignmentNode(resultVariable, node->getTrueExpression());
+ trueBlock->getSequence()->push_back(trueAssignment);
+
+ TIntermBlock *falseBlock = new TIntermBlock();
+ TIntermBinary *falseAssignment =
+ CreateTempAssignmentNode(resultVariable, node->getFalseExpression());
+ falseBlock->getSequence()->push_back(falseAssignment);
+
+ TIntermIfElse *ifNode =
+ new TIntermIfElse(node->getCondition()->getAsTyped(), trueBlock, falseBlock);
+ insertions.push_back(ifNode);
+
+ insertStatementsInParentBlock(insertions);
+
+ TIntermSymbol *ternaryResult = CreateTempSymbolNode(resultVariable);
+ queueReplacement(ternaryResult, OriginalNode::IS_DROPPED);
+
+ return false;
+}
+
+void UnfoldShortCircuitTraverser::nextIteration()
+{
+ mFoundShortCircuit = false;
+}
+
+} // namespace
+
+bool UnfoldShortCircuitToIf(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ UnfoldShortCircuitTraverser traverser(symbolTable);
+ // Unfold one operator at a time, and reset the traverser between iterations.
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.foundShortCircuit())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.foundShortCircuit());
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h
new file mode 100644
index 0000000000..97587e4d38
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// UnfoldShortCircuitToIf is an AST traverser to convert short-circuiting operators to if-else
+// statements.
+// The results are assigned to s# temporaries, which are used by the main translator instead of
+// the original expression.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_UNFOLDSHORTCIRCUIT_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_UNFOLDSHORTCIRCUIT_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool UnfoldShortCircuitToIf(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_UNFOLDSHORTCIRCUIT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.cpp
new file mode 100644
index 0000000000..58a941da0e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.cpp
@@ -0,0 +1,126 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// WrapSwitchStatementsInBlocks.cpp: Wrap switch statements in blocks and declare all switch-scoped
+// variables there to make the AST compatible with HLSL output.
+//
+// switch (init)
+// {
+// case 0:
+// float f;
+// default:
+// f = 1.0;
+// }
+//
+// becomes
+//
+// {
+// float f;
+// switch (init)
+// {
+// case 0:
+// default:
+// f = 1.0;
+// }
+// }
+
+#include "compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class WrapSwitchStatementsInBlocksTraverser : public TIntermTraverser
+{
+ public:
+ WrapSwitchStatementsInBlocksTraverser() : TIntermTraverser(true, false, false) {}
+
+ bool visitSwitch(Visit visit, TIntermSwitch *node) override;
+};
+
+bool WrapSwitchStatementsInBlocksTraverser::visitSwitch(Visit, TIntermSwitch *node)
+{
+ std::vector<TIntermDeclaration *> declarations;
+ TIntermSequence *statementList = node->getStatementList()->getSequence();
+ for (TIntermNode *statement : *statementList)
+ {
+ TIntermDeclaration *asDeclaration = statement->getAsDeclarationNode();
+ if (asDeclaration)
+ {
+ declarations.push_back(asDeclaration);
+ }
+ }
+ if (declarations.empty())
+ {
+ // We don't need to wrap the switch if it doesn't contain declarations as its direct
+ // descendants.
+ return true;
+ }
+
+ TIntermBlock *wrapperBlock = new TIntermBlock();
+ for (TIntermDeclaration *declaration : declarations)
+ {
+ // SeparateDeclarations should have already been run.
+ ASSERT(declaration->getSequence()->size() == 1);
+
+ TIntermDeclaration *declarationInBlock = new TIntermDeclaration();
+ TIntermSymbol *declaratorAsSymbol = declaration->getSequence()->at(0)->getAsSymbolNode();
+ if (declaratorAsSymbol)
+ {
+ // This is a simple declaration like: "float f;"
+ // Remove the declaration from inside the switch and put it in the wrapping block.
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.emplace_back(node->getStatementList(), declaration,
+ std::move(emptyReplacement));
+
+ declarationInBlock->appendDeclarator(declaratorAsSymbol->deepCopy());
+ // The declaration can't be the last statement inside the switch since unused variables
+ // should already have been pruned.
+ ASSERT(declaration != statementList->back());
+ }
+ else
+ {
+ // This is an init declaration like: "float f = 0.0;"
+ // Change the init declaration inside the switch into an assignment and put a plain
+ // declaration in the wrapping block.
+ TIntermBinary *declaratorAsBinary =
+ declaration->getSequence()->at(0)->getAsBinaryNode();
+ ASSERT(declaratorAsBinary);
+
+ TIntermBinary *initAssignment = new TIntermBinary(
+ EOpAssign, declaratorAsBinary->getLeft(), declaratorAsBinary->getRight());
+
+ queueReplacementWithParent(node->getStatementList(), declaration, initAssignment,
+ OriginalNode::IS_DROPPED);
+
+ declarationInBlock->appendDeclarator(declaratorAsBinary->getLeft()->deepCopy());
+ }
+ wrapperBlock->appendStatement(declarationInBlock);
+ }
+
+ wrapperBlock->appendStatement(node);
+ queueReplacement(wrapperBlock, OriginalNode::BECOMES_CHILD);
+
+ // Should be fine to process multiple switch statements, even nesting ones in the same
+ // traversal.
+ return true;
+}
+
+} // anonymous namespace
+
+// Wrap switch statements in the AST into blocks when needed.
+bool WrapSwitchStatementsInBlocks(TCompiler *compiler, TIntermBlock *root)
+{
+ WrapSwitchStatementsInBlocksTraverser traverser;
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h
new file mode 100644
index 0000000000..0c765c306a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// WrapSwitchStatementsInBlocks.h: Wrap switch statements in blocks and declare all switch-scoped
+// variables there to make the AST compatible with HLSL output.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_WRAPSWITCHSTATEMENTSINBLOCKS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_WRAPSWITCHSTATEMENTSINBLOCKS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+
+// Wrap switch statements in the AST into blocks when needed. Returns true if the AST was changed.
+[[nodiscard]] bool WrapSwitchStatementsInBlocks(TCompiler *compiler, TIntermBlock *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_WRAPSWITCHSTATEMENTSINBLOCKS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp
new file mode 100644
index 0000000000..309cb14752
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp
@@ -0,0 +1,54 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ClampFragDepth.cpp: Limit the value that is written to gl_FragDepth to the range [0.0, 1.0].
+// The clamping is run at the very end of shader execution, and is only performed if the shader
+// statically accesses gl_FragDepth.
+//
+
+#include "compiler/translator/tree_ops/gl/ClampFragDepth.h"
+
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/FindSymbolNode.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+namespace sh
+{
+
+bool ClampFragDepth(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ // Only clamp gl_FragDepth if it's used in the shader.
+ if (!FindSymbolNode(root, ImmutableString("gl_FragDepth")))
+ {
+ return true;
+ }
+
+ TIntermSymbol *fragDepthNode = new TIntermSymbol(BuiltInVariable::gl_FragDepth());
+
+ TIntermTyped *minFragDepthNode = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
+
+ TConstantUnion *maxFragDepthConstant = new TConstantUnion();
+ maxFragDepthConstant->setFConst(1.0);
+ TIntermConstantUnion *maxFragDepthNode =
+ new TIntermConstantUnion(maxFragDepthConstant, TType(EbtFloat, EbpHigh, EvqConst));
+
+ // clamp(gl_FragDepth, 0.0, 1.0)
+ TIntermSequence clampArguments;
+ clampArguments.push_back(fragDepthNode->deepCopy());
+ clampArguments.push_back(minFragDepthNode);
+ clampArguments.push_back(maxFragDepthNode);
+ TIntermTyped *clampedFragDepth =
+ CreateBuiltInFunctionCallNode("clamp", &clampArguments, *symbolTable, 100);
+
+ // gl_FragDepth = clamp(gl_FragDepth, 0.0, 1.0)
+ TIntermBinary *assignFragDepth = new TIntermBinary(EOpAssign, fragDepthNode, clampedFragDepth);
+
+ return RunAtTheEndOfShader(compiler, root, assignFragDepth, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.h
new file mode 100644
index 0000000000..70326c9a34
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.h
@@ -0,0 +1,39 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ClampFragDepth.h: Limit the value that is written to gl_FragDepth to the range [0.0, 1.0].
+// The clamping is run at the very end of shader execution, and is only performed if the shader
+// statically accesses gl_FragDepth.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_GL_CLAMPFRAGDEPTH_H_
+#define COMPILER_TRANSLATOR_TREEOPS_GL_CLAMPFRAGDEPTH_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+#ifdef ANGLE_ENABLE_GLSL
+[[nodiscard]] bool ClampFragDepth(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+#else
+[[nodiscard]] ANGLE_INLINE bool ClampFragDepth(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_GL_CLAMPFRAGDEPTH_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.cpp
new file mode 100644
index 0000000000..e15ef32166
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.cpp
@@ -0,0 +1,119 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_ops/gl/RegenerateStructNames.h"
+
+#include "common/debug.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+#include <set>
+
+namespace sh
+{
+
+namespace
+{
+constexpr const ImmutableString kPrefix("_webgl_struct_");
+} // anonymous namespace
+
+class RegenerateStructNamesTraverser : public TIntermTraverser
+{
+ public:
+ RegenerateStructNamesTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable), mScopeDepth(0)
+ {}
+
+ protected:
+ void visitSymbol(TIntermSymbol *) override;
+ bool visitBlock(Visit, TIntermBlock *block) override;
+
+ private:
+ // Indicating the depth of the current scope.
+ // The global scope is 1.
+ int mScopeDepth;
+
+ // If a struct is declared globally, push its ID in this set.
+ std::set<int> mDeclaredGlobalStructs;
+};
+
+void RegenerateStructNamesTraverser::visitSymbol(TIntermSymbol *symbol)
+{
+ ASSERT(symbol);
+ const TType &type = symbol->getType();
+ const TStructure *userType = type.getStruct();
+ if (!userType)
+ return;
+
+ if (userType->symbolType() == SymbolType::BuiltIn ||
+ userType->symbolType() == SymbolType::Empty)
+ {
+ // Built-in struct or nameless struct, do not touch it.
+ return;
+ }
+
+ int uniqueId = userType->uniqueId().get();
+
+ ASSERT(mScopeDepth > 0);
+ if (mScopeDepth == 1)
+ {
+ // If a struct is defined at global scope, we don't map its name.
+ // This is because at global level, the struct might be used to
+ // declare a uniform, so the same name needs to stay the same for
+ // vertex/fragment shaders. However, our mapping uses internal ID,
+ // which will be different for the same struct in vertex/fragment
+ // shaders.
+ // This is OK because names for any structs defined in other scopes
+ // will begin with "_webgl", which is reserved. So there will be
+ // no conflicts among unmapped struct names from global scope and
+ // mapped struct names from other scopes.
+ // However, we need to keep track of these global structs, so if a
+ // variable is used in a local scope, we don't try to modify the
+ // struct name through that variable.
+ mDeclaredGlobalStructs.insert(uniqueId);
+ return;
+ }
+ if (mDeclaredGlobalStructs.count(uniqueId) > 0)
+ return;
+ // Map {name} to _webgl_struct_{uniqueId}_{name}.
+ if (userType->name().beginsWith(kPrefix))
+ {
+ // The name has already been regenerated.
+ return;
+ }
+ ImmutableStringBuilder tmp(kPrefix.length() + sizeof(uniqueId) * 2u + 1u +
+ userType->name().length());
+ tmp << kPrefix;
+ tmp.appendHex(uniqueId);
+ tmp << '_' << userType->name();
+
+ // TODO(oetuaho): Add another mechanism to change symbol names so that the const_cast is not
+ // needed.
+ const_cast<TStructure *>(userType)->setName(tmp);
+}
+
+bool RegenerateStructNamesTraverser::visitBlock(Visit, TIntermBlock *block)
+{
+ ++mScopeDepth;
+ TIntermSequence &sequence = *(block->getSequence());
+ for (TIntermNode *node : sequence)
+ {
+ node->traverse(this);
+ }
+ --mScopeDepth;
+ return false;
+}
+
+bool RegenerateStructNames(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ RegenerateStructNamesTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.h
new file mode 100644
index 0000000000..04cfe6a476
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.h
@@ -0,0 +1,34 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_GL_REGENERATESTRUCTNAMES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_GL_REGENERATESTRUCTNAMES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+#if defined(ANGLE_ENABLE_GLSL)
+[[nodiscard]] bool RegenerateStructNames(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+#else
+[[nodiscard]] ANGLE_INLINE bool RegenerateStructNames(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_GL_REGENERATESTRUCTNAMES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp
new file mode 100644
index 0000000000..83a0f029b8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp
@@ -0,0 +1,97 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteRepeatedAssignToSwizzled.cpp: Rewrite expressions that assign an assignment to a swizzled
+// vector, like:
+// v.x = z = expression;
+// to:
+// z = expression;
+// v.x = z;
+//
+// Note that this doesn't handle some corner cases: expressions nested inside other expressions,
+// inside loop headers, or inside if conditions.
+
+#include "compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h"
+
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class RewriteAssignToSwizzledTraverser : public TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool rewrite(TCompiler *compiler, TIntermBlock *root);
+
+ private:
+ RewriteAssignToSwizzledTraverser();
+
+ bool visitBinary(Visit, TIntermBinary *node) override;
+
+ void nextIteration();
+
+ bool didRewrite() { return mDidRewrite; }
+
+ bool mDidRewrite;
+};
+
+// static
+bool RewriteAssignToSwizzledTraverser::rewrite(TCompiler *compiler, TIntermBlock *root)
+{
+ RewriteAssignToSwizzledTraverser rewrite;
+ do
+ {
+ rewrite.nextIteration();
+ root->traverse(&rewrite);
+ if (!rewrite.updateTree(compiler, root))
+ {
+ return false;
+ }
+ } while (rewrite.didRewrite());
+
+ return true;
+}
+
+RewriteAssignToSwizzledTraverser::RewriteAssignToSwizzledTraverser()
+ : TIntermTraverser(true, false, false), mDidRewrite(false)
+{}
+
+void RewriteAssignToSwizzledTraverser::nextIteration()
+{
+ mDidRewrite = false;
+}
+
+bool RewriteAssignToSwizzledTraverser::visitBinary(Visit, TIntermBinary *node)
+{
+ TIntermBinary *rightBinary = node->getRight()->getAsBinaryNode();
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ if (parentBlock && node->isAssignment() && node->getLeft()->getAsSwizzleNode() && rightBinary &&
+ rightBinary->isAssignment())
+ {
+ TIntermSequence replacements;
+ replacements.push_back(rightBinary);
+ TIntermTyped *rightAssignmentTargetCopy = rightBinary->getLeft()->deepCopy();
+ TIntermBinary *lastAssign =
+ new TIntermBinary(EOpAssign, node->getLeft(), rightAssignmentTargetCopy);
+ replacements.push_back(lastAssign);
+ mMultiReplacements.emplace_back(parentBlock, node, std::move(replacements));
+ mDidRewrite = true;
+ return false;
+ }
+ return true;
+}
+
+} // anonymous namespace
+
+bool RewriteRepeatedAssignToSwizzled(TCompiler *compiler, TIntermBlock *root)
+{
+ return RewriteAssignToSwizzledTraverser::rewrite(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h
new file mode 100644
index 0000000000..1ab9b7ebb8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h
@@ -0,0 +1,40 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteRepeatedAssignToSwizzled.h: Rewrite expressions that assign an assignment to a swizzled
+// vector, like:
+// v.x = z = expression;
+// to:
+// z = expression;
+// v.x = z;
+//
+// Note that this doesn't handle some corner cases: expressions nested inside other expressions,
+// inside loop headers, or inside if conditions.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_GL_REWRITEREPEATEDASSIGNTOSWIZZLED_H_
+#define COMPILER_TRANSLATOR_TREEOPS_GL_REWRITEREPEATEDASSIGNTOSWIZZLED_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+
+#ifdef ANGLE_ENABLE_GLSL
+[[nodiscard]] bool RewriteRepeatedAssignToSwizzled(TCompiler *compiler, TIntermBlock *root);
+#else
+[[nodiscard]] ANGLE_INLINE bool RewriteRepeatedAssignToSwizzled(TCompiler *compiler,
+ TIntermBlock *root)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_GL_REWRITEREPEATEDASSIGNTOSWIZZLED_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.cpp
new file mode 100644
index 0000000000..e94ca2fd17
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.cpp
@@ -0,0 +1,108 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// UseInterfaceBlockFields.cpp: insert statements to reference all members in InterfaceBlock list at
+// the beginning of main. This is to work around a Mac driver that treats unused standard/shared
+// uniform blocks as inactive.
+
+#include "compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void AddNodeUseStatements(TIntermTyped *node, TIntermSequence *sequence)
+{
+ if (node->isArray())
+ {
+ for (unsigned int i = 0u; i < node->getOutermostArraySize(); ++i)
+ {
+ TIntermBinary *element =
+ new TIntermBinary(EOpIndexDirect, node->deepCopy(), CreateIndexNode(i));
+ AddNodeUseStatements(element, sequence);
+ }
+ }
+ else
+ {
+ sequence->insert(sequence->begin(), node);
+ }
+}
+
+void AddFieldUseStatements(const ShaderVariable &var,
+ TIntermSequence *sequence,
+ const TSymbolTable &symbolTable)
+{
+ ASSERT(var.name.find_last_of('[') == std::string::npos);
+ TIntermSymbol *symbol = ReferenceGlobalVariable(ImmutableString(var.name), symbolTable);
+ AddNodeUseStatements(symbol, sequence);
+}
+
+void InsertUseCode(const InterfaceBlock &block, TIntermTyped *blockNode, TIntermSequence *sequence)
+{
+ for (unsigned int i = 0; i < block.fields.size(); ++i)
+ {
+ TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock,
+ blockNode->deepCopy(), CreateIndexNode(i));
+ sequence->insert(sequence->begin(), element);
+ }
+}
+
+void InsertUseCode(TIntermSequence *sequence,
+ const InterfaceBlockList &blocks,
+ const TSymbolTable &symbolTable)
+{
+ for (const auto &block : blocks)
+ {
+ if (block.instanceName.empty())
+ {
+ for (const auto &var : block.fields)
+ {
+ AddFieldUseStatements(var, sequence, symbolTable);
+ }
+ }
+ else if (block.arraySize > 0u)
+ {
+ TIntermSymbol *arraySymbol =
+ ReferenceGlobalVariable(ImmutableString(block.instanceName), symbolTable);
+ for (unsigned int i = 0u; i < block.arraySize; ++i)
+ {
+ TIntermBinary *elementSymbol =
+ new TIntermBinary(EOpIndexDirect, arraySymbol->deepCopy(), CreateIndexNode(i));
+ InsertUseCode(block, elementSymbol, sequence);
+ }
+ }
+ else
+ {
+ TIntermSymbol *blockSymbol =
+ ReferenceGlobalVariable(ImmutableString(block.instanceName), symbolTable);
+ InsertUseCode(block, blockSymbol, sequence);
+ }
+ }
+}
+
+} // namespace
+
+bool UseInterfaceBlockFields(TCompiler *compiler,
+ TIntermBlock *root,
+ const InterfaceBlockList &blocks,
+ const TSymbolTable &symbolTable)
+{
+ TIntermBlock *mainBody = FindMainBody(root);
+ InsertUseCode(mainBody->getSequence(), blocks, symbolTable);
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h
new file mode 100644
index 0000000000..a4f5f3e5e6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h
@@ -0,0 +1,44 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// UseInterfaceBlockFields.h: insert statements to reference all members in InterfaceBlock list at
+// the beginning of main. This is to work around a Mac driver that treats unused standard/shared
+// uniform blocks as inactive.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_GL_USEINTERFACEBLOCKFIELDS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_GL_USEINTERFACEBLOCKFIELDS_H_
+
+#include <GLSLANG/ShaderLang.h>
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+using InterfaceBlockList = std::vector<sh::InterfaceBlock>;
+
+#ifdef ANGLE_ENABLE_GLSL
+[[nodiscard]] bool UseInterfaceBlockFields(TCompiler *compiler,
+ TIntermBlock *root,
+ const InterfaceBlockList &blocks,
+ const TSymbolTable &symbolTable);
+#else
+[[nodiscard]] ANGLE_INLINE bool UseInterfaceBlockFields(TCompiler *compiler,
+ TIntermBlock *root,
+ const InterfaceBlockList &blocks,
+ const TSymbolTable &symbolTable)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_GL_USEINTERFACEBLOCKFIELDS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/AsNode.h b/gfx/angle/checkout/src/compiler/translator/tree_util/AsNode.h
new file mode 100644
index 0000000000..1c6de182d9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/AsNode.h
@@ -0,0 +1,212 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_INTERMASNODE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_INTERMASNODE_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/IntermNode.h"
+
+#include <utility>
+
+namespace sh
+{
+
+namespace priv
+{
+
+template <typename T>
+struct AsNode
+{};
+
+template <>
+struct AsNode<TIntermNode>
+{
+ static ANGLE_INLINE TIntermNode *exec(TIntermNode *node) { return node; }
+};
+
+template <>
+struct AsNode<TIntermTyped>
+{
+ static ANGLE_INLINE TIntermTyped *exec(TIntermNode *node)
+ {
+ return node ? node->getAsTyped() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermSymbol>
+{
+ static ANGLE_INLINE TIntermSymbol *exec(TIntermNode *node)
+ {
+ return node ? node->getAsSymbolNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermConstantUnion>
+{
+ static ANGLE_INLINE TIntermConstantUnion *exec(TIntermNode *node)
+ {
+ return node ? node->getAsConstantUnion() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermFunctionPrototype>
+{
+ static ANGLE_INLINE TIntermFunctionPrototype *exec(TIntermNode *node)
+ {
+ return node ? node->getAsFunctionPrototypeNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermPreprocessorDirective>
+{
+ static ANGLE_INLINE TIntermPreprocessorDirective *exec(TIntermNode *node)
+ {
+ return node ? node->getAsPreprocessorDirective() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermSwizzle>
+{
+ static ANGLE_INLINE TIntermSwizzle *exec(TIntermNode *node)
+ {
+ return node ? node->getAsSwizzleNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermBinary>
+{
+ static ANGLE_INLINE TIntermBinary *exec(TIntermNode *node)
+ {
+ return node ? node->getAsBinaryNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermUnary>
+{
+ static ANGLE_INLINE TIntermUnary *exec(TIntermNode *node)
+ {
+ return node ? node->getAsUnaryNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermTernary>
+{
+ static ANGLE_INLINE TIntermTernary *exec(TIntermNode *node)
+ {
+ return node ? node->getAsTernaryNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermIfElse>
+{
+ static ANGLE_INLINE TIntermIfElse *exec(TIntermNode *node)
+ {
+ return node ? node->getAsIfElseNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermSwitch>
+{
+ static ANGLE_INLINE TIntermSwitch *exec(TIntermNode *node)
+ {
+ return node ? node->getAsSwitchNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermCase>
+{
+ static ANGLE_INLINE TIntermCase *exec(TIntermNode *node)
+ {
+ return node ? node->getAsCaseNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermFunctionDefinition>
+{
+ static ANGLE_INLINE TIntermFunctionDefinition *exec(TIntermNode *node)
+ {
+ return node ? node->getAsFunctionDefinition() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermAggregate>
+{
+ static ANGLE_INLINE TIntermAggregate *exec(TIntermNode *node)
+ {
+ return node ? node->getAsAggregate() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermBlock>
+{
+ static ANGLE_INLINE TIntermBlock *exec(TIntermNode *node)
+ {
+ return node ? node->getAsBlock() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermGlobalQualifierDeclaration>
+{
+ static ANGLE_INLINE TIntermGlobalQualifierDeclaration *exec(TIntermNode *node)
+ {
+ return node ? node->getAsGlobalQualifierDeclarationNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermDeclaration>
+{
+ static ANGLE_INLINE TIntermDeclaration *exec(TIntermNode *node)
+ {
+ return node ? node->getAsDeclarationNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermLoop>
+{
+ static ANGLE_INLINE TIntermLoop *exec(TIntermNode *node)
+ {
+ return node ? node->getAsLoopNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermBranch>
+{
+ static ANGLE_INLINE TIntermBranch *exec(TIntermNode *node)
+ {
+ return node ? node->getAsBranchNode() : nullptr;
+ }
+};
+
+} // namespace priv
+
+template <typename T>
+ANGLE_INLINE T *asNode(TIntermNode *node)
+{
+ return priv::AsNode<T>::exec(node);
+}
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_INTERMASNODE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn.h b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn.h
new file mode 100644
index 0000000000..22c33f9fc0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn.h
@@ -0,0 +1,18 @@
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// BuiltIn.h:
+// Chooses BuiltIn_complete_autogen.h or BuiltIn_ESSL_autogen.h
+// depending on whether platform is android
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_H_
+
+#if defined(ANDROID)
+# include "BuiltIn_ESSL_autogen.h"
+#else
+# include "BuiltIn_complete_autogen.h"
+#endif
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_ESSL_autogen.h b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_ESSL_autogen.h
new file mode 100644
index 0000000000..5380d82c68
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_ESSL_autogen.h
@@ -0,0 +1,4177 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// BuiltIn_ESSL_autogen.h:
+// Compile-time initialized built-ins.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
+
+#include "compiler/translator/SymbolUniqueId.h"
+
+namespace sh
+{
+
+class TVariable;
+
+class BuiltInId
+{
+ public:
+ static constexpr const TSymbolUniqueId radians_Float1 = TSymbolUniqueId(3086);
+ static constexpr const TSymbolUniqueId pt00B = TSymbolUniqueId(3087);
+ static constexpr const TSymbolUniqueId radians_Float2 = TSymbolUniqueId(3088);
+ static constexpr const TSymbolUniqueId pt10B = TSymbolUniqueId(3089);
+ static constexpr const TSymbolUniqueId radians_Float3 = TSymbolUniqueId(3090);
+ static constexpr const TSymbolUniqueId pt20B = TSymbolUniqueId(3091);
+ static constexpr const TSymbolUniqueId radians_Float4 = TSymbolUniqueId(3092);
+ static constexpr const TSymbolUniqueId pt30B = TSymbolUniqueId(3093);
+ static constexpr const TSymbolUniqueId degrees_Float1 = TSymbolUniqueId(3094);
+ static constexpr const TSymbolUniqueId degrees_Float2 = TSymbolUniqueId(3095);
+ static constexpr const TSymbolUniqueId degrees_Float3 = TSymbolUniqueId(3096);
+ static constexpr const TSymbolUniqueId degrees_Float4 = TSymbolUniqueId(3097);
+ static constexpr const TSymbolUniqueId sin_Float1 = TSymbolUniqueId(3098);
+ static constexpr const TSymbolUniqueId sin_Float2 = TSymbolUniqueId(3099);
+ static constexpr const TSymbolUniqueId sin_Float3 = TSymbolUniqueId(3100);
+ static constexpr const TSymbolUniqueId sin_Float4 = TSymbolUniqueId(3101);
+ static constexpr const TSymbolUniqueId cos_Float1 = TSymbolUniqueId(3102);
+ static constexpr const TSymbolUniqueId cos_Float2 = TSymbolUniqueId(3103);
+ static constexpr const TSymbolUniqueId cos_Float3 = TSymbolUniqueId(3104);
+ static constexpr const TSymbolUniqueId cos_Float4 = TSymbolUniqueId(3105);
+ static constexpr const TSymbolUniqueId tan_Float1 = TSymbolUniqueId(3106);
+ static constexpr const TSymbolUniqueId tan_Float2 = TSymbolUniqueId(3107);
+ static constexpr const TSymbolUniqueId tan_Float3 = TSymbolUniqueId(3108);
+ static constexpr const TSymbolUniqueId tan_Float4 = TSymbolUniqueId(3109);
+ static constexpr const TSymbolUniqueId asin_Float1 = TSymbolUniqueId(3110);
+ static constexpr const TSymbolUniqueId asin_Float2 = TSymbolUniqueId(3111);
+ static constexpr const TSymbolUniqueId asin_Float3 = TSymbolUniqueId(3112);
+ static constexpr const TSymbolUniqueId asin_Float4 = TSymbolUniqueId(3113);
+ static constexpr const TSymbolUniqueId acos_Float1 = TSymbolUniqueId(3114);
+ static constexpr const TSymbolUniqueId acos_Float2 = TSymbolUniqueId(3115);
+ static constexpr const TSymbolUniqueId acos_Float3 = TSymbolUniqueId(3116);
+ static constexpr const TSymbolUniqueId acos_Float4 = TSymbolUniqueId(3117);
+ static constexpr const TSymbolUniqueId atan_Float1_Float1 = TSymbolUniqueId(3118);
+ static constexpr const TSymbolUniqueId atan_Float2_Float2 = TSymbolUniqueId(3119);
+ static constexpr const TSymbolUniqueId atan_Float3_Float3 = TSymbolUniqueId(3120);
+ static constexpr const TSymbolUniqueId atan_Float4_Float4 = TSymbolUniqueId(3121);
+ static constexpr const TSymbolUniqueId atan_Float1 = TSymbolUniqueId(3122);
+ static constexpr const TSymbolUniqueId atan_Float2 = TSymbolUniqueId(3123);
+ static constexpr const TSymbolUniqueId atan_Float3 = TSymbolUniqueId(3124);
+ static constexpr const TSymbolUniqueId atan_Float4 = TSymbolUniqueId(3125);
+ static constexpr const TSymbolUniqueId sinh_Float1 = TSymbolUniqueId(3126);
+ static constexpr const TSymbolUniqueId sinh_Float2 = TSymbolUniqueId(3127);
+ static constexpr const TSymbolUniqueId sinh_Float3 = TSymbolUniqueId(3128);
+ static constexpr const TSymbolUniqueId sinh_Float4 = TSymbolUniqueId(3129);
+ static constexpr const TSymbolUniqueId cosh_Float1 = TSymbolUniqueId(3130);
+ static constexpr const TSymbolUniqueId cosh_Float2 = TSymbolUniqueId(3131);
+ static constexpr const TSymbolUniqueId cosh_Float3 = TSymbolUniqueId(3132);
+ static constexpr const TSymbolUniqueId cosh_Float4 = TSymbolUniqueId(3133);
+ static constexpr const TSymbolUniqueId tanh_Float1 = TSymbolUniqueId(3134);
+ static constexpr const TSymbolUniqueId tanh_Float2 = TSymbolUniqueId(3135);
+ static constexpr const TSymbolUniqueId tanh_Float3 = TSymbolUniqueId(3136);
+ static constexpr const TSymbolUniqueId tanh_Float4 = TSymbolUniqueId(3137);
+ static constexpr const TSymbolUniqueId asinh_Float1 = TSymbolUniqueId(3138);
+ static constexpr const TSymbolUniqueId asinh_Float2 = TSymbolUniqueId(3139);
+ static constexpr const TSymbolUniqueId asinh_Float3 = TSymbolUniqueId(3140);
+ static constexpr const TSymbolUniqueId asinh_Float4 = TSymbolUniqueId(3141);
+ static constexpr const TSymbolUniqueId acosh_Float1 = TSymbolUniqueId(3142);
+ static constexpr const TSymbolUniqueId acosh_Float2 = TSymbolUniqueId(3143);
+ static constexpr const TSymbolUniqueId acosh_Float3 = TSymbolUniqueId(3144);
+ static constexpr const TSymbolUniqueId acosh_Float4 = TSymbolUniqueId(3145);
+ static constexpr const TSymbolUniqueId atanh_Float1 = TSymbolUniqueId(3146);
+ static constexpr const TSymbolUniqueId atanh_Float2 = TSymbolUniqueId(3147);
+ static constexpr const TSymbolUniqueId atanh_Float3 = TSymbolUniqueId(3148);
+ static constexpr const TSymbolUniqueId atanh_Float4 = TSymbolUniqueId(3149);
+ static constexpr const TSymbolUniqueId pow_Float1_Float1 = TSymbolUniqueId(3150);
+ static constexpr const TSymbolUniqueId pow_Float2_Float2 = TSymbolUniqueId(3151);
+ static constexpr const TSymbolUniqueId pow_Float3_Float3 = TSymbolUniqueId(3152);
+ static constexpr const TSymbolUniqueId pow_Float4_Float4 = TSymbolUniqueId(3153);
+ static constexpr const TSymbolUniqueId exp_Float1 = TSymbolUniqueId(3154);
+ static constexpr const TSymbolUniqueId exp_Float2 = TSymbolUniqueId(3155);
+ static constexpr const TSymbolUniqueId exp_Float3 = TSymbolUniqueId(3156);
+ static constexpr const TSymbolUniqueId exp_Float4 = TSymbolUniqueId(3157);
+ static constexpr const TSymbolUniqueId log_Float1 = TSymbolUniqueId(3158);
+ static constexpr const TSymbolUniqueId log_Float2 = TSymbolUniqueId(3159);
+ static constexpr const TSymbolUniqueId log_Float3 = TSymbolUniqueId(3160);
+ static constexpr const TSymbolUniqueId log_Float4 = TSymbolUniqueId(3161);
+ static constexpr const TSymbolUniqueId exp2_Float1 = TSymbolUniqueId(3162);
+ static constexpr const TSymbolUniqueId exp2_Float2 = TSymbolUniqueId(3163);
+ static constexpr const TSymbolUniqueId exp2_Float3 = TSymbolUniqueId(3164);
+ static constexpr const TSymbolUniqueId exp2_Float4 = TSymbolUniqueId(3165);
+ static constexpr const TSymbolUniqueId log2_Float1 = TSymbolUniqueId(3166);
+ static constexpr const TSymbolUniqueId log2_Float2 = TSymbolUniqueId(3167);
+ static constexpr const TSymbolUniqueId log2_Float3 = TSymbolUniqueId(3168);
+ static constexpr const TSymbolUniqueId log2_Float4 = TSymbolUniqueId(3169);
+ static constexpr const TSymbolUniqueId sqrt_Float1 = TSymbolUniqueId(3170);
+ static constexpr const TSymbolUniqueId sqrt_Float2 = TSymbolUniqueId(3171);
+ static constexpr const TSymbolUniqueId sqrt_Float3 = TSymbolUniqueId(3172);
+ static constexpr const TSymbolUniqueId sqrt_Float4 = TSymbolUniqueId(3173);
+ static constexpr const TSymbolUniqueId inversesqrt_Float1 = TSymbolUniqueId(3174);
+ static constexpr const TSymbolUniqueId inversesqrt_Float2 = TSymbolUniqueId(3175);
+ static constexpr const TSymbolUniqueId inversesqrt_Float3 = TSymbolUniqueId(3176);
+ static constexpr const TSymbolUniqueId inversesqrt_Float4 = TSymbolUniqueId(3177);
+ static constexpr const TSymbolUniqueId abs_Float1 = TSymbolUniqueId(3178);
+ static constexpr const TSymbolUniqueId abs_Float2 = TSymbolUniqueId(3179);
+ static constexpr const TSymbolUniqueId abs_Float3 = TSymbolUniqueId(3180);
+ static constexpr const TSymbolUniqueId abs_Float4 = TSymbolUniqueId(3181);
+ static constexpr const TSymbolUniqueId abs_Int1 = TSymbolUniqueId(3182);
+ static constexpr const TSymbolUniqueId pt00D = TSymbolUniqueId(3183);
+ static constexpr const TSymbolUniqueId abs_Int2 = TSymbolUniqueId(3184);
+ static constexpr const TSymbolUniqueId pt10D = TSymbolUniqueId(3185);
+ static constexpr const TSymbolUniqueId abs_Int3 = TSymbolUniqueId(3186);
+ static constexpr const TSymbolUniqueId pt20D = TSymbolUniqueId(3187);
+ static constexpr const TSymbolUniqueId abs_Int4 = TSymbolUniqueId(3188);
+ static constexpr const TSymbolUniqueId pt30D = TSymbolUniqueId(3189);
+ static constexpr const TSymbolUniqueId sign_Float1 = TSymbolUniqueId(3190);
+ static constexpr const TSymbolUniqueId sign_Float2 = TSymbolUniqueId(3191);
+ static constexpr const TSymbolUniqueId sign_Float3 = TSymbolUniqueId(3192);
+ static constexpr const TSymbolUniqueId sign_Float4 = TSymbolUniqueId(3193);
+ static constexpr const TSymbolUniqueId sign_Int1 = TSymbolUniqueId(3194);
+ static constexpr const TSymbolUniqueId sign_Int2 = TSymbolUniqueId(3195);
+ static constexpr const TSymbolUniqueId sign_Int3 = TSymbolUniqueId(3196);
+ static constexpr const TSymbolUniqueId sign_Int4 = TSymbolUniqueId(3197);
+ static constexpr const TSymbolUniqueId floor_Float1 = TSymbolUniqueId(3198);
+ static constexpr const TSymbolUniqueId floor_Float2 = TSymbolUniqueId(3199);
+ static constexpr const TSymbolUniqueId floor_Float3 = TSymbolUniqueId(3200);
+ static constexpr const TSymbolUniqueId floor_Float4 = TSymbolUniqueId(3201);
+ static constexpr const TSymbolUniqueId trunc_Float1 = TSymbolUniqueId(3202);
+ static constexpr const TSymbolUniqueId trunc_Float2 = TSymbolUniqueId(3203);
+ static constexpr const TSymbolUniqueId trunc_Float3 = TSymbolUniqueId(3204);
+ static constexpr const TSymbolUniqueId trunc_Float4 = TSymbolUniqueId(3205);
+ static constexpr const TSymbolUniqueId round_Float1 = TSymbolUniqueId(3206);
+ static constexpr const TSymbolUniqueId round_Float2 = TSymbolUniqueId(3207);
+ static constexpr const TSymbolUniqueId round_Float3 = TSymbolUniqueId(3208);
+ static constexpr const TSymbolUniqueId round_Float4 = TSymbolUniqueId(3209);
+ static constexpr const TSymbolUniqueId roundEven_Float1 = TSymbolUniqueId(3210);
+ static constexpr const TSymbolUniqueId roundEven_Float2 = TSymbolUniqueId(3211);
+ static constexpr const TSymbolUniqueId roundEven_Float3 = TSymbolUniqueId(3212);
+ static constexpr const TSymbolUniqueId roundEven_Float4 = TSymbolUniqueId(3213);
+ static constexpr const TSymbolUniqueId ceil_Float1 = TSymbolUniqueId(3214);
+ static constexpr const TSymbolUniqueId ceil_Float2 = TSymbolUniqueId(3215);
+ static constexpr const TSymbolUniqueId ceil_Float3 = TSymbolUniqueId(3216);
+ static constexpr const TSymbolUniqueId ceil_Float4 = TSymbolUniqueId(3217);
+ static constexpr const TSymbolUniqueId fract_Float1 = TSymbolUniqueId(3218);
+ static constexpr const TSymbolUniqueId fract_Float2 = TSymbolUniqueId(3219);
+ static constexpr const TSymbolUniqueId fract_Float3 = TSymbolUniqueId(3220);
+ static constexpr const TSymbolUniqueId fract_Float4 = TSymbolUniqueId(3221);
+ static constexpr const TSymbolUniqueId mod_Float1_Float1 = TSymbolUniqueId(3222);
+ static constexpr const TSymbolUniqueId mod_Float2_Float1 = TSymbolUniqueId(3223);
+ static constexpr const TSymbolUniqueId mod_Float3_Float1 = TSymbolUniqueId(3224);
+ static constexpr const TSymbolUniqueId mod_Float4_Float1 = TSymbolUniqueId(3225);
+ static constexpr const TSymbolUniqueId mod_Float2_Float2 = TSymbolUniqueId(3226);
+ static constexpr const TSymbolUniqueId mod_Float3_Float3 = TSymbolUniqueId(3227);
+ static constexpr const TSymbolUniqueId mod_Float4_Float4 = TSymbolUniqueId(3228);
+ static constexpr const TSymbolUniqueId min_Float1_Float1 = TSymbolUniqueId(3229);
+ static constexpr const TSymbolUniqueId min_Float2_Float1 = TSymbolUniqueId(3230);
+ static constexpr const TSymbolUniqueId min_Float3_Float1 = TSymbolUniqueId(3231);
+ static constexpr const TSymbolUniqueId min_Float4_Float1 = TSymbolUniqueId(3232);
+ static constexpr const TSymbolUniqueId min_Float2_Float2 = TSymbolUniqueId(3233);
+ static constexpr const TSymbolUniqueId min_Float3_Float3 = TSymbolUniqueId(3234);
+ static constexpr const TSymbolUniqueId min_Float4_Float4 = TSymbolUniqueId(3235);
+ static constexpr const TSymbolUniqueId min_Int1_Int1 = TSymbolUniqueId(3236);
+ static constexpr const TSymbolUniqueId min_Int2_Int2 = TSymbolUniqueId(3237);
+ static constexpr const TSymbolUniqueId min_Int3_Int3 = TSymbolUniqueId(3238);
+ static constexpr const TSymbolUniqueId min_Int4_Int4 = TSymbolUniqueId(3239);
+ static constexpr const TSymbolUniqueId min_Int2_Int1 = TSymbolUniqueId(3240);
+ static constexpr const TSymbolUniqueId min_Int3_Int1 = TSymbolUniqueId(3241);
+ static constexpr const TSymbolUniqueId min_Int4_Int1 = TSymbolUniqueId(3242);
+ static constexpr const TSymbolUniqueId min_UInt1_UInt1 = TSymbolUniqueId(3243);
+ static constexpr const TSymbolUniqueId pt00E = TSymbolUniqueId(3244);
+ static constexpr const TSymbolUniqueId min_UInt2_UInt2 = TSymbolUniqueId(3245);
+ static constexpr const TSymbolUniqueId pt10E = TSymbolUniqueId(3246);
+ static constexpr const TSymbolUniqueId min_UInt3_UInt3 = TSymbolUniqueId(3247);
+ static constexpr const TSymbolUniqueId pt20E = TSymbolUniqueId(3248);
+ static constexpr const TSymbolUniqueId min_UInt4_UInt4 = TSymbolUniqueId(3249);
+ static constexpr const TSymbolUniqueId pt30E = TSymbolUniqueId(3250);
+ static constexpr const TSymbolUniqueId min_UInt2_UInt1 = TSymbolUniqueId(3251);
+ static constexpr const TSymbolUniqueId min_UInt3_UInt1 = TSymbolUniqueId(3252);
+ static constexpr const TSymbolUniqueId min_UInt4_UInt1 = TSymbolUniqueId(3253);
+ static constexpr const TSymbolUniqueId max_Float1_Float1 = TSymbolUniqueId(3254);
+ static constexpr const TSymbolUniqueId max_Float2_Float1 = TSymbolUniqueId(3255);
+ static constexpr const TSymbolUniqueId max_Float3_Float1 = TSymbolUniqueId(3256);
+ static constexpr const TSymbolUniqueId max_Float4_Float1 = TSymbolUniqueId(3257);
+ static constexpr const TSymbolUniqueId max_Float2_Float2 = TSymbolUniqueId(3258);
+ static constexpr const TSymbolUniqueId max_Float3_Float3 = TSymbolUniqueId(3259);
+ static constexpr const TSymbolUniqueId max_Float4_Float4 = TSymbolUniqueId(3260);
+ static constexpr const TSymbolUniqueId max_Int1_Int1 = TSymbolUniqueId(3261);
+ static constexpr const TSymbolUniqueId max_Int2_Int2 = TSymbolUniqueId(3262);
+ static constexpr const TSymbolUniqueId max_Int3_Int3 = TSymbolUniqueId(3263);
+ static constexpr const TSymbolUniqueId max_Int4_Int4 = TSymbolUniqueId(3264);
+ static constexpr const TSymbolUniqueId max_Int2_Int1 = TSymbolUniqueId(3265);
+ static constexpr const TSymbolUniqueId max_Int3_Int1 = TSymbolUniqueId(3266);
+ static constexpr const TSymbolUniqueId max_Int4_Int1 = TSymbolUniqueId(3267);
+ static constexpr const TSymbolUniqueId max_UInt1_UInt1 = TSymbolUniqueId(3268);
+ static constexpr const TSymbolUniqueId max_UInt2_UInt2 = TSymbolUniqueId(3269);
+ static constexpr const TSymbolUniqueId max_UInt3_UInt3 = TSymbolUniqueId(3270);
+ static constexpr const TSymbolUniqueId max_UInt4_UInt4 = TSymbolUniqueId(3271);
+ static constexpr const TSymbolUniqueId max_UInt2_UInt1 = TSymbolUniqueId(3272);
+ static constexpr const TSymbolUniqueId max_UInt3_UInt1 = TSymbolUniqueId(3273);
+ static constexpr const TSymbolUniqueId max_UInt4_UInt1 = TSymbolUniqueId(3274);
+ static constexpr const TSymbolUniqueId clamp_Float1_Float1_Float1 = TSymbolUniqueId(3275);
+ static constexpr const TSymbolUniqueId clamp_Float2_Float1_Float1 = TSymbolUniqueId(3276);
+ static constexpr const TSymbolUniqueId clamp_Float3_Float1_Float1 = TSymbolUniqueId(3277);
+ static constexpr const TSymbolUniqueId clamp_Float4_Float1_Float1 = TSymbolUniqueId(3278);
+ static constexpr const TSymbolUniqueId clamp_Float2_Float2_Float2 = TSymbolUniqueId(3279);
+ static constexpr const TSymbolUniqueId clamp_Float3_Float3_Float3 = TSymbolUniqueId(3280);
+ static constexpr const TSymbolUniqueId clamp_Float4_Float4_Float4 = TSymbolUniqueId(3281);
+ static constexpr const TSymbolUniqueId clamp_Int1_Int1_Int1 = TSymbolUniqueId(3282);
+ static constexpr const TSymbolUniqueId clamp_Int2_Int1_Int1 = TSymbolUniqueId(3283);
+ static constexpr const TSymbolUniqueId clamp_Int3_Int1_Int1 = TSymbolUniqueId(3284);
+ static constexpr const TSymbolUniqueId clamp_Int4_Int1_Int1 = TSymbolUniqueId(3285);
+ static constexpr const TSymbolUniqueId clamp_Int2_Int2_Int2 = TSymbolUniqueId(3286);
+ static constexpr const TSymbolUniqueId clamp_Int3_Int3_Int3 = TSymbolUniqueId(3287);
+ static constexpr const TSymbolUniqueId clamp_Int4_Int4_Int4 = TSymbolUniqueId(3288);
+ static constexpr const TSymbolUniqueId clamp_UInt1_UInt1_UInt1 = TSymbolUniqueId(3289);
+ static constexpr const TSymbolUniqueId clamp_UInt2_UInt1_UInt1 = TSymbolUniqueId(3290);
+ static constexpr const TSymbolUniqueId clamp_UInt3_UInt1_UInt1 = TSymbolUniqueId(3291);
+ static constexpr const TSymbolUniqueId clamp_UInt4_UInt1_UInt1 = TSymbolUniqueId(3292);
+ static constexpr const TSymbolUniqueId clamp_UInt2_UInt2_UInt2 = TSymbolUniqueId(3293);
+ static constexpr const TSymbolUniqueId clamp_UInt3_UInt3_UInt3 = TSymbolUniqueId(3294);
+ static constexpr const TSymbolUniqueId clamp_UInt4_UInt4_UInt4 = TSymbolUniqueId(3295);
+ static constexpr const TSymbolUniqueId mix_Float1_Float1_Float1 = TSymbolUniqueId(3296);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Float1 = TSymbolUniqueId(3297);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Float1 = TSymbolUniqueId(3298);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Float1 = TSymbolUniqueId(3299);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Float2 = TSymbolUniqueId(3300);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Float3 = TSymbolUniqueId(3301);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Float4 = TSymbolUniqueId(3302);
+ static constexpr const TSymbolUniqueId mix_Float1_Float1_Bool1 = TSymbolUniqueId(3303);
+ static constexpr const TSymbolUniqueId pt00F = TSymbolUniqueId(3304);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Bool2 = TSymbolUniqueId(3305);
+ static constexpr const TSymbolUniqueId pt10F = TSymbolUniqueId(3306);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Bool3 = TSymbolUniqueId(3307);
+ static constexpr const TSymbolUniqueId pt20F = TSymbolUniqueId(3308);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Bool4 = TSymbolUniqueId(3309);
+ static constexpr const TSymbolUniqueId pt30F = TSymbolUniqueId(3310);
+ static constexpr const TSymbolUniqueId mix_Int1_Int1_Bool1 = TSymbolUniqueId(3311);
+ static constexpr const TSymbolUniqueId mix_Int2_Int2_Bool2 = TSymbolUniqueId(3312);
+ static constexpr const TSymbolUniqueId mix_Int3_Int3_Bool3 = TSymbolUniqueId(3313);
+ static constexpr const TSymbolUniqueId mix_Int4_Int4_Bool4 = TSymbolUniqueId(3314);
+ static constexpr const TSymbolUniqueId mix_UInt1_UInt1_Bool1 = TSymbolUniqueId(3315);
+ static constexpr const TSymbolUniqueId mix_UInt2_UInt2_Bool2 = TSymbolUniqueId(3316);
+ static constexpr const TSymbolUniqueId mix_UInt3_UInt3_Bool3 = TSymbolUniqueId(3317);
+ static constexpr const TSymbolUniqueId mix_UInt4_UInt4_Bool4 = TSymbolUniqueId(3318);
+ static constexpr const TSymbolUniqueId mix_Bool1_Bool1_Bool1 = TSymbolUniqueId(3319);
+ static constexpr const TSymbolUniqueId mix_Bool2_Bool2_Bool2 = TSymbolUniqueId(3320);
+ static constexpr const TSymbolUniqueId mix_Bool3_Bool3_Bool3 = TSymbolUniqueId(3321);
+ static constexpr const TSymbolUniqueId mix_Bool4_Bool4_Bool4 = TSymbolUniqueId(3322);
+ static constexpr const TSymbolUniqueId step_Float1_Float1 = TSymbolUniqueId(3323);
+ static constexpr const TSymbolUniqueId step_Float2_Float2 = TSymbolUniqueId(3324);
+ static constexpr const TSymbolUniqueId step_Float3_Float3 = TSymbolUniqueId(3325);
+ static constexpr const TSymbolUniqueId step_Float4_Float4 = TSymbolUniqueId(3326);
+ static constexpr const TSymbolUniqueId step_Float1_Float2 = TSymbolUniqueId(3327);
+ static constexpr const TSymbolUniqueId step_Float1_Float3 = TSymbolUniqueId(3328);
+ static constexpr const TSymbolUniqueId step_Float1_Float4 = TSymbolUniqueId(3329);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float1 = TSymbolUniqueId(3330);
+ static constexpr const TSymbolUniqueId smoothstep_Float2_Float2_Float2 = TSymbolUniqueId(3331);
+ static constexpr const TSymbolUniqueId smoothstep_Float3_Float3_Float3 = TSymbolUniqueId(3332);
+ static constexpr const TSymbolUniqueId smoothstep_Float4_Float4_Float4 = TSymbolUniqueId(3333);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float2 = TSymbolUniqueId(3334);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float3 = TSymbolUniqueId(3335);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float4 = TSymbolUniqueId(3336);
+ static constexpr const TSymbolUniqueId modf_Float1_Float1 = TSymbolUniqueId(3337);
+ static constexpr const TSymbolUniqueId pt_o_00B = TSymbolUniqueId(3338);
+ static constexpr const TSymbolUniqueId modf_Float2_Float2 = TSymbolUniqueId(3339);
+ static constexpr const TSymbolUniqueId pt_o_10B = TSymbolUniqueId(3340);
+ static constexpr const TSymbolUniqueId modf_Float3_Float3 = TSymbolUniqueId(3341);
+ static constexpr const TSymbolUniqueId pt_o_20B = TSymbolUniqueId(3342);
+ static constexpr const TSymbolUniqueId modf_Float4_Float4 = TSymbolUniqueId(3343);
+ static constexpr const TSymbolUniqueId pt_o_30B = TSymbolUniqueId(3344);
+ static constexpr const TSymbolUniqueId isnan_Float1 = TSymbolUniqueId(3345);
+ static constexpr const TSymbolUniqueId isnan_Float2 = TSymbolUniqueId(3346);
+ static constexpr const TSymbolUniqueId isnan_Float3 = TSymbolUniqueId(3347);
+ static constexpr const TSymbolUniqueId isnan_Float4 = TSymbolUniqueId(3348);
+ static constexpr const TSymbolUniqueId isinf_Float1 = TSymbolUniqueId(3349);
+ static constexpr const TSymbolUniqueId isinf_Float2 = TSymbolUniqueId(3350);
+ static constexpr const TSymbolUniqueId isinf_Float3 = TSymbolUniqueId(3351);
+ static constexpr const TSymbolUniqueId isinf_Float4 = TSymbolUniqueId(3352);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float1 = TSymbolUniqueId(3353);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float2 = TSymbolUniqueId(3354);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float3 = TSymbolUniqueId(3355);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float4 = TSymbolUniqueId(3356);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float1 = TSymbolUniqueId(3357);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float2 = TSymbolUniqueId(3358);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float3 = TSymbolUniqueId(3359);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float4 = TSymbolUniqueId(3360);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int1 = TSymbolUniqueId(3361);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int2 = TSymbolUniqueId(3362);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int3 = TSymbolUniqueId(3363);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int4 = TSymbolUniqueId(3364);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt1 = TSymbolUniqueId(3365);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt2 = TSymbolUniqueId(3366);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt3 = TSymbolUniqueId(3367);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt4 = TSymbolUniqueId(3368);
+ static constexpr const TSymbolUniqueId fma_Float1_Float1_Float1 = TSymbolUniqueId(3369);
+ static constexpr const TSymbolUniqueId fma_Float2_Float2_Float2 = TSymbolUniqueId(3370);
+ static constexpr const TSymbolUniqueId fma_Float3_Float3_Float3 = TSymbolUniqueId(3371);
+ static constexpr const TSymbolUniqueId fma_Float4_Float4_Float4 = TSymbolUniqueId(3372);
+ static constexpr const TSymbolUniqueId fmaExt_Float1_Float1_Float1 = TSymbolUniqueId(3373);
+ static constexpr const TSymbolUniqueId fmaExt_Float2_Float2_Float2 = TSymbolUniqueId(3374);
+ static constexpr const TSymbolUniqueId fmaExt_Float3_Float3_Float3 = TSymbolUniqueId(3375);
+ static constexpr const TSymbolUniqueId fmaExt_Float4_Float4_Float4 = TSymbolUniqueId(3376);
+ static constexpr const TSymbolUniqueId frexp_Float1_Int1 = TSymbolUniqueId(3377);
+ static constexpr const TSymbolUniqueId pt_o_00D = TSymbolUniqueId(3378);
+ static constexpr const TSymbolUniqueId frexp_Float2_Int2 = TSymbolUniqueId(3379);
+ static constexpr const TSymbolUniqueId pt_o_10D = TSymbolUniqueId(3380);
+ static constexpr const TSymbolUniqueId frexp_Float3_Int3 = TSymbolUniqueId(3381);
+ static constexpr const TSymbolUniqueId pt_o_20D = TSymbolUniqueId(3382);
+ static constexpr const TSymbolUniqueId frexp_Float4_Int4 = TSymbolUniqueId(3383);
+ static constexpr const TSymbolUniqueId pt_o_30D = TSymbolUniqueId(3384);
+ static constexpr const TSymbolUniqueId ldexp_Float1_Int1 = TSymbolUniqueId(3385);
+ static constexpr const TSymbolUniqueId ldexp_Float2_Int2 = TSymbolUniqueId(3386);
+ static constexpr const TSymbolUniqueId ldexp_Float3_Int3 = TSymbolUniqueId(3387);
+ static constexpr const TSymbolUniqueId ldexp_Float4_Int4 = TSymbolUniqueId(3388);
+ static constexpr const TSymbolUniqueId packSnorm2x16_Float2 = TSymbolUniqueId(3389);
+ static constexpr const TSymbolUniqueId packHalf2x16_Float2 = TSymbolUniqueId(3390);
+ static constexpr const TSymbolUniqueId unpackSnorm2x16_UInt1 = TSymbolUniqueId(3391);
+ static constexpr const TSymbolUniqueId unpackHalf2x16_UInt1 = TSymbolUniqueId(3392);
+ static constexpr const TSymbolUniqueId packUnorm2x16_Float2 = TSymbolUniqueId(3393);
+ static constexpr const TSymbolUniqueId unpackUnorm2x16_UInt1 = TSymbolUniqueId(3394);
+ static constexpr const TSymbolUniqueId packUnorm4x8_Float4 = TSymbolUniqueId(3395);
+ static constexpr const TSymbolUniqueId packSnorm4x8_Float4 = TSymbolUniqueId(3396);
+ static constexpr const TSymbolUniqueId unpackUnorm4x8_UInt1 = TSymbolUniqueId(3397);
+ static constexpr const TSymbolUniqueId unpackSnorm4x8_UInt1 = TSymbolUniqueId(3398);
+ static constexpr const TSymbolUniqueId length_Float1 = TSymbolUniqueId(3399);
+ static constexpr const TSymbolUniqueId length_Float2 = TSymbolUniqueId(3400);
+ static constexpr const TSymbolUniqueId length_Float3 = TSymbolUniqueId(3401);
+ static constexpr const TSymbolUniqueId length_Float4 = TSymbolUniqueId(3402);
+ static constexpr const TSymbolUniqueId distance_Float1_Float1 = TSymbolUniqueId(3403);
+ static constexpr const TSymbolUniqueId distance_Float2_Float2 = TSymbolUniqueId(3404);
+ static constexpr const TSymbolUniqueId distance_Float3_Float3 = TSymbolUniqueId(3405);
+ static constexpr const TSymbolUniqueId distance_Float4_Float4 = TSymbolUniqueId(3406);
+ static constexpr const TSymbolUniqueId dot_Float1_Float1 = TSymbolUniqueId(3407);
+ static constexpr const TSymbolUniqueId dot_Float2_Float2 = TSymbolUniqueId(3408);
+ static constexpr const TSymbolUniqueId dot_Float3_Float3 = TSymbolUniqueId(3409);
+ static constexpr const TSymbolUniqueId dot_Float4_Float4 = TSymbolUniqueId(3410);
+ static constexpr const TSymbolUniqueId cross_Float3_Float3 = TSymbolUniqueId(3411);
+ static constexpr const TSymbolUniqueId normalize_Float1 = TSymbolUniqueId(3412);
+ static constexpr const TSymbolUniqueId normalize_Float2 = TSymbolUniqueId(3413);
+ static constexpr const TSymbolUniqueId normalize_Float3 = TSymbolUniqueId(3414);
+ static constexpr const TSymbolUniqueId normalize_Float4 = TSymbolUniqueId(3415);
+ static constexpr const TSymbolUniqueId faceforward_Float1_Float1_Float1 = TSymbolUniqueId(3416);
+ static constexpr const TSymbolUniqueId faceforward_Float2_Float2_Float2 = TSymbolUniqueId(3417);
+ static constexpr const TSymbolUniqueId faceforward_Float3_Float3_Float3 = TSymbolUniqueId(3418);
+ static constexpr const TSymbolUniqueId faceforward_Float4_Float4_Float4 = TSymbolUniqueId(3419);
+ static constexpr const TSymbolUniqueId reflect_Float1_Float1 = TSymbolUniqueId(3420);
+ static constexpr const TSymbolUniqueId reflect_Float2_Float2 = TSymbolUniqueId(3421);
+ static constexpr const TSymbolUniqueId reflect_Float3_Float3 = TSymbolUniqueId(3422);
+ static constexpr const TSymbolUniqueId reflect_Float4_Float4 = TSymbolUniqueId(3423);
+ static constexpr const TSymbolUniqueId refract_Float1_Float1_Float1 = TSymbolUniqueId(3424);
+ static constexpr const TSymbolUniqueId refract_Float2_Float2_Float1 = TSymbolUniqueId(3425);
+ static constexpr const TSymbolUniqueId refract_Float3_Float3_Float1 = TSymbolUniqueId(3426);
+ static constexpr const TSymbolUniqueId refract_Float4_Float4_Float1 = TSymbolUniqueId(3427);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x2_Float2x2 = TSymbolUniqueId(3428);
+ static constexpr const TSymbolUniqueId pt50B = TSymbolUniqueId(3429);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x3_Float3x3 = TSymbolUniqueId(3430);
+ static constexpr const TSymbolUniqueId ptA0B = TSymbolUniqueId(3431);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x4_Float4x4 = TSymbolUniqueId(3432);
+ static constexpr const TSymbolUniqueId ptF0B = TSymbolUniqueId(3433);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x3_Float2x3 = TSymbolUniqueId(3434);
+ static constexpr const TSymbolUniqueId pt90B = TSymbolUniqueId(3435);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x2_Float3x2 = TSymbolUniqueId(3436);
+ static constexpr const TSymbolUniqueId pt60B = TSymbolUniqueId(3437);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x4_Float2x4 = TSymbolUniqueId(3438);
+ static constexpr const TSymbolUniqueId ptD0B = TSymbolUniqueId(3439);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x2_Float4x2 = TSymbolUniqueId(3440);
+ static constexpr const TSymbolUniqueId pt70B = TSymbolUniqueId(3441);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x4_Float3x4 = TSymbolUniqueId(3442);
+ static constexpr const TSymbolUniqueId ptE0B = TSymbolUniqueId(3443);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x3_Float4x3 = TSymbolUniqueId(3444);
+ static constexpr const TSymbolUniqueId ptB0B = TSymbolUniqueId(3445);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float2 = TSymbolUniqueId(3446);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float3 = TSymbolUniqueId(3447);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float4 = TSymbolUniqueId(3448);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float2 = TSymbolUniqueId(3449);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float3 = TSymbolUniqueId(3450);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float2 = TSymbolUniqueId(3451);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float4 = TSymbolUniqueId(3452);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float3 = TSymbolUniqueId(3453);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float4 = TSymbolUniqueId(3454);
+ static constexpr const TSymbolUniqueId transpose_Float2x2 = TSymbolUniqueId(3455);
+ static constexpr const TSymbolUniqueId transpose_Float3x3 = TSymbolUniqueId(3456);
+ static constexpr const TSymbolUniqueId transpose_Float4x4 = TSymbolUniqueId(3457);
+ static constexpr const TSymbolUniqueId transpose_Float3x2 = TSymbolUniqueId(3458);
+ static constexpr const TSymbolUniqueId transpose_Float2x3 = TSymbolUniqueId(3459);
+ static constexpr const TSymbolUniqueId transpose_Float4x2 = TSymbolUniqueId(3460);
+ static constexpr const TSymbolUniqueId transpose_Float2x4 = TSymbolUniqueId(3461);
+ static constexpr const TSymbolUniqueId transpose_Float4x3 = TSymbolUniqueId(3462);
+ static constexpr const TSymbolUniqueId transpose_Float3x4 = TSymbolUniqueId(3463);
+ static constexpr const TSymbolUniqueId determinant_Float2x2 = TSymbolUniqueId(3464);
+ static constexpr const TSymbolUniqueId determinant_Float3x3 = TSymbolUniqueId(3465);
+ static constexpr const TSymbolUniqueId determinant_Float4x4 = TSymbolUniqueId(3466);
+ static constexpr const TSymbolUniqueId inverse_Float2x2 = TSymbolUniqueId(3467);
+ static constexpr const TSymbolUniqueId inverse_Float3x3 = TSymbolUniqueId(3468);
+ static constexpr const TSymbolUniqueId inverse_Float4x4 = TSymbolUniqueId(3469);
+ static constexpr const TSymbolUniqueId lessThan_Float2_Float2 = TSymbolUniqueId(3470);
+ static constexpr const TSymbolUniqueId lessThan_Float3_Float3 = TSymbolUniqueId(3471);
+ static constexpr const TSymbolUniqueId lessThan_Float4_Float4 = TSymbolUniqueId(3472);
+ static constexpr const TSymbolUniqueId lessThan_Int2_Int2 = TSymbolUniqueId(3473);
+ static constexpr const TSymbolUniqueId lessThan_Int3_Int3 = TSymbolUniqueId(3474);
+ static constexpr const TSymbolUniqueId lessThan_Int4_Int4 = TSymbolUniqueId(3475);
+ static constexpr const TSymbolUniqueId lessThan_UInt2_UInt2 = TSymbolUniqueId(3476);
+ static constexpr const TSymbolUniqueId lessThan_UInt3_UInt3 = TSymbolUniqueId(3477);
+ static constexpr const TSymbolUniqueId lessThan_UInt4_UInt4 = TSymbolUniqueId(3478);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float2_Float2 = TSymbolUniqueId(3479);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float3_Float3 = TSymbolUniqueId(3480);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float4_Float4 = TSymbolUniqueId(3481);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int2_Int2 = TSymbolUniqueId(3482);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int3_Int3 = TSymbolUniqueId(3483);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int4_Int4 = TSymbolUniqueId(3484);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt2_UInt2 = TSymbolUniqueId(3485);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt3_UInt3 = TSymbolUniqueId(3486);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt4_UInt4 = TSymbolUniqueId(3487);
+ static constexpr const TSymbolUniqueId greaterThan_Float2_Float2 = TSymbolUniqueId(3488);
+ static constexpr const TSymbolUniqueId greaterThan_Float3_Float3 = TSymbolUniqueId(3489);
+ static constexpr const TSymbolUniqueId greaterThan_Float4_Float4 = TSymbolUniqueId(3490);
+ static constexpr const TSymbolUniqueId greaterThan_Int2_Int2 = TSymbolUniqueId(3491);
+ static constexpr const TSymbolUniqueId greaterThan_Int3_Int3 = TSymbolUniqueId(3492);
+ static constexpr const TSymbolUniqueId greaterThan_Int4_Int4 = TSymbolUniqueId(3493);
+ static constexpr const TSymbolUniqueId greaterThan_UInt2_UInt2 = TSymbolUniqueId(3494);
+ static constexpr const TSymbolUniqueId greaterThan_UInt3_UInt3 = TSymbolUniqueId(3495);
+ static constexpr const TSymbolUniqueId greaterThan_UInt4_UInt4 = TSymbolUniqueId(3496);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float2_Float2 = TSymbolUniqueId(3497);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float3_Float3 = TSymbolUniqueId(3498);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float4_Float4 = TSymbolUniqueId(3499);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int2_Int2 = TSymbolUniqueId(3500);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int3_Int3 = TSymbolUniqueId(3501);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int4_Int4 = TSymbolUniqueId(3502);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt2_UInt2 = TSymbolUniqueId(3503);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt3_UInt3 = TSymbolUniqueId(3504);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt4_UInt4 = TSymbolUniqueId(3505);
+ static constexpr const TSymbolUniqueId equal_Float2_Float2 = TSymbolUniqueId(3506);
+ static constexpr const TSymbolUniqueId equal_Float3_Float3 = TSymbolUniqueId(3507);
+ static constexpr const TSymbolUniqueId equal_Float4_Float4 = TSymbolUniqueId(3508);
+ static constexpr const TSymbolUniqueId equal_Int2_Int2 = TSymbolUniqueId(3509);
+ static constexpr const TSymbolUniqueId equal_Int3_Int3 = TSymbolUniqueId(3510);
+ static constexpr const TSymbolUniqueId equal_Int4_Int4 = TSymbolUniqueId(3511);
+ static constexpr const TSymbolUniqueId equal_UInt2_UInt2 = TSymbolUniqueId(3512);
+ static constexpr const TSymbolUniqueId equal_UInt3_UInt3 = TSymbolUniqueId(3513);
+ static constexpr const TSymbolUniqueId equal_UInt4_UInt4 = TSymbolUniqueId(3514);
+ static constexpr const TSymbolUniqueId equal_Bool2_Bool2 = TSymbolUniqueId(3515);
+ static constexpr const TSymbolUniqueId equal_Bool3_Bool3 = TSymbolUniqueId(3516);
+ static constexpr const TSymbolUniqueId equal_Bool4_Bool4 = TSymbolUniqueId(3517);
+ static constexpr const TSymbolUniqueId notEqual_Float2_Float2 = TSymbolUniqueId(3518);
+ static constexpr const TSymbolUniqueId notEqual_Float3_Float3 = TSymbolUniqueId(3519);
+ static constexpr const TSymbolUniqueId notEqual_Float4_Float4 = TSymbolUniqueId(3520);
+ static constexpr const TSymbolUniqueId notEqual_Int2_Int2 = TSymbolUniqueId(3521);
+ static constexpr const TSymbolUniqueId notEqual_Int3_Int3 = TSymbolUniqueId(3522);
+ static constexpr const TSymbolUniqueId notEqual_Int4_Int4 = TSymbolUniqueId(3523);
+ static constexpr const TSymbolUniqueId notEqual_UInt2_UInt2 = TSymbolUniqueId(3524);
+ static constexpr const TSymbolUniqueId notEqual_UInt3_UInt3 = TSymbolUniqueId(3525);
+ static constexpr const TSymbolUniqueId notEqual_UInt4_UInt4 = TSymbolUniqueId(3526);
+ static constexpr const TSymbolUniqueId notEqual_Bool2_Bool2 = TSymbolUniqueId(3527);
+ static constexpr const TSymbolUniqueId notEqual_Bool3_Bool3 = TSymbolUniqueId(3528);
+ static constexpr const TSymbolUniqueId notEqual_Bool4_Bool4 = TSymbolUniqueId(3529);
+ static constexpr const TSymbolUniqueId any_Bool2 = TSymbolUniqueId(3530);
+ static constexpr const TSymbolUniqueId any_Bool3 = TSymbolUniqueId(3531);
+ static constexpr const TSymbolUniqueId any_Bool4 = TSymbolUniqueId(3532);
+ static constexpr const TSymbolUniqueId all_Bool2 = TSymbolUniqueId(3533);
+ static constexpr const TSymbolUniqueId all_Bool3 = TSymbolUniqueId(3534);
+ static constexpr const TSymbolUniqueId all_Bool4 = TSymbolUniqueId(3535);
+ static constexpr const TSymbolUniqueId notFunc_Bool2 = TSymbolUniqueId(3536);
+ static constexpr const TSymbolUniqueId notFunc_Bool3 = TSymbolUniqueId(3537);
+ static constexpr const TSymbolUniqueId notFunc_Bool4 = TSymbolUniqueId(3538);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int1_Int1_Int1 = TSymbolUniqueId(3539);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int2_Int1_Int1 = TSymbolUniqueId(3540);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int3_Int1_Int1 = TSymbolUniqueId(3541);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int4_Int1_Int1 = TSymbolUniqueId(3542);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt1_Int1_Int1 = TSymbolUniqueId(3543);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt2_Int1_Int1 = TSymbolUniqueId(3544);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt3_Int1_Int1 = TSymbolUniqueId(3545);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt4_Int1_Int1 = TSymbolUniqueId(3546);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int1_Int1_Int1_Int1 =
+ TSymbolUniqueId(3547);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int2_Int2_Int1_Int1 =
+ TSymbolUniqueId(3548);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int3_Int3_Int1_Int1 =
+ TSymbolUniqueId(3549);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int4_Int4_Int1_Int1 =
+ TSymbolUniqueId(3550);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt1_UInt1_Int1_Int1 =
+ TSymbolUniqueId(3551);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt2_UInt2_Int1_Int1 =
+ TSymbolUniqueId(3552);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt3_UInt3_Int1_Int1 =
+ TSymbolUniqueId(3553);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt4_UInt4_Int1_Int1 =
+ TSymbolUniqueId(3554);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int1 = TSymbolUniqueId(3555);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int2 = TSymbolUniqueId(3556);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int3 = TSymbolUniqueId(3557);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int4 = TSymbolUniqueId(3558);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt1 = TSymbolUniqueId(3559);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt2 = TSymbolUniqueId(3560);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt3 = TSymbolUniqueId(3561);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt4 = TSymbolUniqueId(3562);
+ static constexpr const TSymbolUniqueId bitCount_Int1 = TSymbolUniqueId(3563);
+ static constexpr const TSymbolUniqueId bitCount_Int2 = TSymbolUniqueId(3564);
+ static constexpr const TSymbolUniqueId bitCount_Int3 = TSymbolUniqueId(3565);
+ static constexpr const TSymbolUniqueId bitCount_Int4 = TSymbolUniqueId(3566);
+ static constexpr const TSymbolUniqueId bitCount_UInt1 = TSymbolUniqueId(3567);
+ static constexpr const TSymbolUniqueId bitCount_UInt2 = TSymbolUniqueId(3568);
+ static constexpr const TSymbolUniqueId bitCount_UInt3 = TSymbolUniqueId(3569);
+ static constexpr const TSymbolUniqueId bitCount_UInt4 = TSymbolUniqueId(3570);
+ static constexpr const TSymbolUniqueId findLSB_Int1 = TSymbolUniqueId(3571);
+ static constexpr const TSymbolUniqueId findLSB_Int2 = TSymbolUniqueId(3572);
+ static constexpr const TSymbolUniqueId findLSB_Int3 = TSymbolUniqueId(3573);
+ static constexpr const TSymbolUniqueId findLSB_Int4 = TSymbolUniqueId(3574);
+ static constexpr const TSymbolUniqueId findLSB_UInt1 = TSymbolUniqueId(3575);
+ static constexpr const TSymbolUniqueId findLSB_UInt2 = TSymbolUniqueId(3576);
+ static constexpr const TSymbolUniqueId findLSB_UInt3 = TSymbolUniqueId(3577);
+ static constexpr const TSymbolUniqueId findLSB_UInt4 = TSymbolUniqueId(3578);
+ static constexpr const TSymbolUniqueId findMSB_Int1 = TSymbolUniqueId(3579);
+ static constexpr const TSymbolUniqueId findMSB_Int2 = TSymbolUniqueId(3580);
+ static constexpr const TSymbolUniqueId findMSB_Int3 = TSymbolUniqueId(3581);
+ static constexpr const TSymbolUniqueId findMSB_Int4 = TSymbolUniqueId(3582);
+ static constexpr const TSymbolUniqueId findMSB_UInt1 = TSymbolUniqueId(3583);
+ static constexpr const TSymbolUniqueId findMSB_UInt2 = TSymbolUniqueId(3584);
+ static constexpr const TSymbolUniqueId findMSB_UInt3 = TSymbolUniqueId(3585);
+ static constexpr const TSymbolUniqueId findMSB_UInt4 = TSymbolUniqueId(3586);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt1_UInt1_UInt1 = TSymbolUniqueId(3587);
+ static constexpr const TSymbolUniqueId pt_o_00E = TSymbolUniqueId(3588);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt2_UInt2_UInt2 = TSymbolUniqueId(3589);
+ static constexpr const TSymbolUniqueId pt_o_10E = TSymbolUniqueId(3590);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt3_UInt3_UInt3 = TSymbolUniqueId(3591);
+ static constexpr const TSymbolUniqueId pt_o_20E = TSymbolUniqueId(3592);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt4_UInt4_UInt4 = TSymbolUniqueId(3593);
+ static constexpr const TSymbolUniqueId pt_o_30E = TSymbolUniqueId(3594);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt1_UInt1_UInt1 = TSymbolUniqueId(3595);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt2_UInt2_UInt2 = TSymbolUniqueId(3596);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt3_UInt3_UInt3 = TSymbolUniqueId(3597);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt4_UInt4_UInt4 = TSymbolUniqueId(3598);
+ static constexpr const TSymbolUniqueId umulExtended_UInt1_UInt1_UInt1_UInt1 =
+ TSymbolUniqueId(3599);
+ static constexpr const TSymbolUniqueId umulExtended_UInt2_UInt2_UInt2_UInt2 =
+ TSymbolUniqueId(3600);
+ static constexpr const TSymbolUniqueId umulExtended_UInt3_UInt3_UInt3_UInt3 =
+ TSymbolUniqueId(3601);
+ static constexpr const TSymbolUniqueId umulExtended_UInt4_UInt4_UInt4_UInt4 =
+ TSymbolUniqueId(3602);
+ static constexpr const TSymbolUniqueId imulExtended_Int1_Int1_Int1_Int1 = TSymbolUniqueId(3603);
+ static constexpr const TSymbolUniqueId imulExtended_Int2_Int2_Int2_Int2 = TSymbolUniqueId(3604);
+ static constexpr const TSymbolUniqueId imulExtended_Int3_Int3_Int3_Int3 = TSymbolUniqueId(3605);
+ static constexpr const TSymbolUniqueId imulExtended_Int4_Int4_Int4_Int4 = TSymbolUniqueId(3606);
+ static constexpr const TSymbolUniqueId texture2D_Sampler2D1_Float2 = TSymbolUniqueId(3607);
+ static constexpr const TSymbolUniqueId pt00I = TSymbolUniqueId(3608);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float3 = TSymbolUniqueId(3609);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float4 = TSymbolUniqueId(3610);
+ static constexpr const TSymbolUniqueId textureCube_SamplerCube1_Float3 = TSymbolUniqueId(3611);
+ static constexpr const TSymbolUniqueId pt00K = TSymbolUniqueId(3612);
+ static constexpr const TSymbolUniqueId texture3D_Sampler3D1_Float3 = TSymbolUniqueId(3613);
+ static constexpr const TSymbolUniqueId pt00J = TSymbolUniqueId(3614);
+ static constexpr const TSymbolUniqueId texture3DProj_Sampler3D1_Float4 = TSymbolUniqueId(3615);
+ static constexpr const TSymbolUniqueId shadow2DEXT_Sampler2DShadow1_Float3 =
+ TSymbolUniqueId(3616);
+ static constexpr const TSymbolUniqueId pt00d = TSymbolUniqueId(3617);
+ static constexpr const TSymbolUniqueId shadow2DProjEXT_Sampler2DShadow1_Float4 =
+ TSymbolUniqueId(3618);
+ static constexpr const TSymbolUniqueId texture2D_SamplerExternalOES1_Float2 =
+ TSymbolUniqueId(3619);
+ static constexpr const TSymbolUniqueId pt00M = TSymbolUniqueId(3620);
+ static constexpr const TSymbolUniqueId texture2DProj_SamplerExternalOES1_Float3 =
+ TSymbolUniqueId(3621);
+ static constexpr const TSymbolUniqueId texture2DProj_SamplerExternalOES1_Float4 =
+ TSymbolUniqueId(3622);
+ static constexpr const TSymbolUniqueId texture2DRect_Sampler2DRect1_Float2 =
+ TSymbolUniqueId(3623);
+ static constexpr const TSymbolUniqueId pt00O = TSymbolUniqueId(3624);
+ static constexpr const TSymbolUniqueId texture2DRectProj_Sampler2DRect1_Float3 =
+ TSymbolUniqueId(3625);
+ static constexpr const TSymbolUniqueId texture2DRectProj_Sampler2DRect1_Float4 =
+ TSymbolUniqueId(3626);
+ static constexpr const TSymbolUniqueId texture2DGradEXT_Sampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(3627);
+ static constexpr const TSymbolUniqueId texture2DProjGradEXT_Sampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3628);
+ static constexpr const TSymbolUniqueId texture2DProjGradEXT_Sampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3629);
+ static constexpr const TSymbolUniqueId textureCubeGradEXT_SamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3630);
+ static constexpr const TSymbolUniqueId textureVideoWEBGL_SamplerVideoWEBGL1_Float2 =
+ TSymbolUniqueId(3631);
+ static constexpr const TSymbolUniqueId pt00y = TSymbolUniqueId(3632);
+ static constexpr const TSymbolUniqueId texture2D_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3633);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3634);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3635);
+ static constexpr const TSymbolUniqueId textureCube_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3636);
+ static constexpr const TSymbolUniqueId texture3D_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3637);
+ static constexpr const TSymbolUniqueId texture3DProj_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3638);
+ static constexpr const TSymbolUniqueId texture3DLod_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3639);
+ static constexpr const TSymbolUniqueId texture3DProjLod_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3640);
+ static constexpr const TSymbolUniqueId texture2DLod_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3641);
+ static constexpr const TSymbolUniqueId texture2DProjLod_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3642);
+ static constexpr const TSymbolUniqueId texture2DProjLod_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3643);
+ static constexpr const TSymbolUniqueId textureCubeLod_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3644);
+ static constexpr const TSymbolUniqueId texture2DLodEXT_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3645);
+ static constexpr const TSymbolUniqueId texture2DProjLodEXT_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3646);
+ static constexpr const TSymbolUniqueId texture2DProjLodEXT_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3647);
+ static constexpr const TSymbolUniqueId textureCubeLodEXT_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3648);
+ static constexpr const TSymbolUniqueId texture_Sampler2D1_Float2 = TSymbolUniqueId(3649);
+ static constexpr const TSymbolUniqueId texture_ISampler2D1_Float2 = TSymbolUniqueId(3650);
+ static constexpr const TSymbolUniqueId pt00R = TSymbolUniqueId(3651);
+ static constexpr const TSymbolUniqueId texture_USampler2D1_Float2 = TSymbolUniqueId(3652);
+ static constexpr const TSymbolUniqueId pt00X = TSymbolUniqueId(3653);
+ static constexpr const TSymbolUniqueId texture_Sampler3D1_Float3 = TSymbolUniqueId(3654);
+ static constexpr const TSymbolUniqueId texture_ISampler3D1_Float3 = TSymbolUniqueId(3655);
+ static constexpr const TSymbolUniqueId pt00S = TSymbolUniqueId(3656);
+ static constexpr const TSymbolUniqueId texture_USampler3D1_Float3 = TSymbolUniqueId(3657);
+ static constexpr const TSymbolUniqueId pt00Y = TSymbolUniqueId(3658);
+ static constexpr const TSymbolUniqueId texture_SamplerCube1_Float3 = TSymbolUniqueId(3659);
+ static constexpr const TSymbolUniqueId texture_ISamplerCube1_Float3 = TSymbolUniqueId(3660);
+ static constexpr const TSymbolUniqueId pt00T = TSymbolUniqueId(3661);
+ static constexpr const TSymbolUniqueId texture_USamplerCube1_Float3 = TSymbolUniqueId(3662);
+ static constexpr const TSymbolUniqueId pt00Z = TSymbolUniqueId(3663);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArray1_Float3 = TSymbolUniqueId(3664);
+ static constexpr const TSymbolUniqueId pt00L = TSymbolUniqueId(3665);
+ static constexpr const TSymbolUniqueId texture_ISampler2DArray1_Float3 = TSymbolUniqueId(3666);
+ static constexpr const TSymbolUniqueId pt00U = TSymbolUniqueId(3667);
+ static constexpr const TSymbolUniqueId texture_USampler2DArray1_Float3 = TSymbolUniqueId(3668);
+ static constexpr const TSymbolUniqueId pt00a = TSymbolUniqueId(3669);
+ static constexpr const TSymbolUniqueId texture_Sampler2DShadow1_Float3 = TSymbolUniqueId(3670);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeShadow1_Float4 =
+ TSymbolUniqueId(3671);
+ static constexpr const TSymbolUniqueId pt00e = TSymbolUniqueId(3672);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArrayShadow1_Float4 =
+ TSymbolUniqueId(3673);
+ static constexpr const TSymbolUniqueId pt00f = TSymbolUniqueId(3674);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArray1_Float4 = TSymbolUniqueId(3675);
+ static constexpr const TSymbolUniqueId pt00k = TSymbolUniqueId(3676);
+ static constexpr const TSymbolUniqueId texture_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3677);
+ static constexpr const TSymbolUniqueId pt00s = TSymbolUniqueId(3678);
+ static constexpr const TSymbolUniqueId texture_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3679);
+ static constexpr const TSymbolUniqueId pt00x = TSymbolUniqueId(3680);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(3681);
+ static constexpr const TSymbolUniqueId pt00l = TSymbolUniqueId(3682);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3683);
+ static constexpr const TSymbolUniqueId textureExt_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3684);
+ static constexpr const TSymbolUniqueId textureExt_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3685);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(3686);
+ static constexpr const TSymbolUniqueId texture_SamplerExternalOES1_Float2 =
+ TSymbolUniqueId(3687);
+ static constexpr const TSymbolUniqueId texture_SamplerExternal2DY2YEXT1_Float2 =
+ TSymbolUniqueId(3688);
+ static constexpr const TSymbolUniqueId pt00N = TSymbolUniqueId(3689);
+ static constexpr const TSymbolUniqueId texture_Sampler2DRect1_Float2 = TSymbolUniqueId(3690);
+ static constexpr const TSymbolUniqueId texture_SamplerVideoWEBGL1_Float2 =
+ TSymbolUniqueId(3691);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float3 = TSymbolUniqueId(3692);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float3 = TSymbolUniqueId(3693);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float3 = TSymbolUniqueId(3694);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float4 = TSymbolUniqueId(3695);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float4 = TSymbolUniqueId(3696);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float4 = TSymbolUniqueId(3697);
+ static constexpr const TSymbolUniqueId textureProj_Sampler3D1_Float4 = TSymbolUniqueId(3698);
+ static constexpr const TSymbolUniqueId textureProj_ISampler3D1_Float4 = TSymbolUniqueId(3699);
+ static constexpr const TSymbolUniqueId textureProj_USampler3D1_Float4 = TSymbolUniqueId(3700);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DShadow1_Float4 =
+ TSymbolUniqueId(3701);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float3 =
+ TSymbolUniqueId(3702);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float4 =
+ TSymbolUniqueId(3703);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float3 =
+ TSymbolUniqueId(3704);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float4 =
+ TSymbolUniqueId(3705);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DRect1_Float3 =
+ TSymbolUniqueId(3706);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DRect1_Float4 =
+ TSymbolUniqueId(3707);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3708);
+ static constexpr const TSymbolUniqueId textureLod_ISampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3709);
+ static constexpr const TSymbolUniqueId textureLod_USampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3710);
+ static constexpr const TSymbolUniqueId textureLod_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3711);
+ static constexpr const TSymbolUniqueId textureLod_ISampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3712);
+ static constexpr const TSymbolUniqueId textureLod_USampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3713);
+ static constexpr const TSymbolUniqueId textureLod_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3714);
+ static constexpr const TSymbolUniqueId textureLod_ISamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3715);
+ static constexpr const TSymbolUniqueId textureLod_USamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3716);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3717);
+ static constexpr const TSymbolUniqueId textureLod_ISampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3718);
+ static constexpr const TSymbolUniqueId textureLod_USampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3719);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(3720);
+ static constexpr const TSymbolUniqueId textureLod_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3721);
+ static constexpr const TSymbolUniqueId textureLod_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3722);
+ static constexpr const TSymbolUniqueId textureLod_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3723);
+ static constexpr const TSymbolUniqueId textureLodExt_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3724);
+ static constexpr const TSymbolUniqueId textureLodExt_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3725);
+ static constexpr const TSymbolUniqueId textureLodExt_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3726);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2D1_Int1 = TSymbolUniqueId(3727);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2D1_Int1 = TSymbolUniqueId(3728);
+ static constexpr const TSymbolUniqueId textureSize_USampler2D1_Int1 = TSymbolUniqueId(3729);
+ static constexpr const TSymbolUniqueId textureSize_Sampler3D1_Int1 = TSymbolUniqueId(3730);
+ static constexpr const TSymbolUniqueId textureSize_ISampler3D1_Int1 = TSymbolUniqueId(3731);
+ static constexpr const TSymbolUniqueId textureSize_USampler3D1_Int1 = TSymbolUniqueId(3732);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCube1_Int1 = TSymbolUniqueId(3733);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerCube1_Int1 = TSymbolUniqueId(3734);
+ static constexpr const TSymbolUniqueId textureSize_USamplerCube1_Int1 = TSymbolUniqueId(3735);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DArray1_Int1 = TSymbolUniqueId(3736);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DArray1_Int1 =
+ TSymbolUniqueId(3737);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DArray1_Int1 =
+ TSymbolUniqueId(3738);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DShadow1_Int1 =
+ TSymbolUniqueId(3739);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeShadow1_Int1 =
+ TSymbolUniqueId(3740);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DArrayShadow1_Int1 =
+ TSymbolUniqueId(3741);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3742);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3743);
+ static constexpr const TSymbolUniqueId textureSize_USamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3744);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeArrayShadow1_Int1 =
+ TSymbolUniqueId(3745);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3746);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3747);
+ static constexpr const TSymbolUniqueId textureSizeExt_USamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3748);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerCubeArrayShadow1_Int1 =
+ TSymbolUniqueId(3749);
+ static constexpr const TSymbolUniqueId textureSize_SamplerBuffer1 = TSymbolUniqueId(3750);
+ static constexpr const TSymbolUniqueId pt00j = TSymbolUniqueId(3751);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerBuffer1 = TSymbolUniqueId(3752);
+ static constexpr const TSymbolUniqueId pt00r = TSymbolUniqueId(3753);
+ static constexpr const TSymbolUniqueId textureSize_USamplerBuffer1 = TSymbolUniqueId(3754);
+ static constexpr const TSymbolUniqueId pt00w = TSymbolUniqueId(3755);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerBuffer1 = TSymbolUniqueId(3756);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISamplerBuffer1 = TSymbolUniqueId(3757);
+ static constexpr const TSymbolUniqueId textureSizeExt_USamplerBuffer1 = TSymbolUniqueId(3758);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DMS1 = TSymbolUniqueId(3759);
+ static constexpr const TSymbolUniqueId pt00P = TSymbolUniqueId(3760);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DMS1 = TSymbolUniqueId(3761);
+ static constexpr const TSymbolUniqueId pt00V = TSymbolUniqueId(3762);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DMS1 = TSymbolUniqueId(3763);
+ static constexpr const TSymbolUniqueId pt00b = TSymbolUniqueId(3764);
+ static constexpr const TSymbolUniqueId textureSizeExt_Sampler2DMS1 = TSymbolUniqueId(3765);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISampler2DMS1 = TSymbolUniqueId(3766);
+ static constexpr const TSymbolUniqueId textureSizeExt_USampler2DMS1 = TSymbolUniqueId(3767);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DMSArray1 = TSymbolUniqueId(3768);
+ static constexpr const TSymbolUniqueId pt00Q = TSymbolUniqueId(3769);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DMSArray1 = TSymbolUniqueId(3770);
+ static constexpr const TSymbolUniqueId pt00W = TSymbolUniqueId(3771);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DMSArray1 = TSymbolUniqueId(3772);
+ static constexpr const TSymbolUniqueId pt00c = TSymbolUniqueId(3773);
+ static constexpr const TSymbolUniqueId textureSizeExt_Sampler2DMSArray1 = TSymbolUniqueId(3774);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISampler2DMSArray1 =
+ TSymbolUniqueId(3775);
+ static constexpr const TSymbolUniqueId textureSizeExt_USampler2DMSArray1 =
+ TSymbolUniqueId(3776);
+ static constexpr const TSymbolUniqueId textureSize_SamplerExternalOES1_Int1 =
+ TSymbolUniqueId(3777);
+ static constexpr const TSymbolUniqueId textureSize_SamplerExternal2DY2YEXT1_Int1 =
+ TSymbolUniqueId(3778);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3779);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3780);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3781);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3782);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3783);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3784);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3785);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3786);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3787);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(3788);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2D1_Int2_Int1 = TSymbolUniqueId(3789);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2D1_Int2_Int1 = TSymbolUniqueId(3790);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2D1_Int2_Int1 = TSymbolUniqueId(3791);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler3D1_Int3_Int1 = TSymbolUniqueId(3792);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler3D1_Int3_Int1 = TSymbolUniqueId(3793);
+ static constexpr const TSymbolUniqueId texelFetch_USampler3D1_Int3_Int1 = TSymbolUniqueId(3794);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(3795);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(3796);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(3797);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerBuffer1_Int1 = TSymbolUniqueId(3798);
+ static constexpr const TSymbolUniqueId texelFetch_ISamplerBuffer1_Int1 = TSymbolUniqueId(3799);
+ static constexpr const TSymbolUniqueId texelFetch_USamplerBuffer1_Int1 = TSymbolUniqueId(3800);
+ static constexpr const TSymbolUniqueId texelFetchExt_SamplerBuffer1_Int1 =
+ TSymbolUniqueId(3801);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISamplerBuffer1_Int1 =
+ TSymbolUniqueId(3802);
+ static constexpr const TSymbolUniqueId texelFetchExt_USamplerBuffer1_Int1 =
+ TSymbolUniqueId(3803);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3804);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3805);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3806);
+ static constexpr const TSymbolUniqueId texelFetchExt_Sampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3807);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3808);
+ static constexpr const TSymbolUniqueId texelFetchExt_USampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3809);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3810);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3811);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3812);
+ static constexpr const TSymbolUniqueId texelFetchExt_Sampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3813);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3814);
+ static constexpr const TSymbolUniqueId texelFetchExt_USampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3815);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerExternalOES1_Int2_Int1 =
+ TSymbolUniqueId(3816);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerExternal2DY2YEXT1_Int2_Int1 =
+ TSymbolUniqueId(3817);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(3818);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(3819);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(3820);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3821);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3822);
+ static constexpr const TSymbolUniqueId textureGrad_USampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3823);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3824);
+ static constexpr const TSymbolUniqueId textureGrad_ISamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3825);
+ static constexpr const TSymbolUniqueId textureGrad_USamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3826);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DShadow1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3827);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCubeShadow1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3828);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3829);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3830);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3831);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DArrayShadow1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3832);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3833);
+ static constexpr const TSymbolUniqueId textureGrad_ISamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3834);
+ static constexpr const TSymbolUniqueId textureGrad_USamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3835);
+ static constexpr const TSymbolUniqueId textureGradExt_SamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3836);
+ static constexpr const TSymbolUniqueId textureGradExt_ISamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3837);
+ static constexpr const TSymbolUniqueId textureGradExt_USamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3838);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3839);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3840);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3841);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3842);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3843);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3844);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3845);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3846);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3847);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2DShadow1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3848);
+ static constexpr const TSymbolUniqueId texture_Sampler2D1_Float2_Float1 = TSymbolUniqueId(3849);
+ static constexpr const TSymbolUniqueId texture_ISampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3850);
+ static constexpr const TSymbolUniqueId texture_USampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3851);
+ static constexpr const TSymbolUniqueId texture_Sampler3D1_Float3_Float1 = TSymbolUniqueId(3852);
+ static constexpr const TSymbolUniqueId texture_ISampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3853);
+ static constexpr const TSymbolUniqueId texture_USampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3854);
+ static constexpr const TSymbolUniqueId texture_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3855);
+ static constexpr const TSymbolUniqueId texture_ISamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3856);
+ static constexpr const TSymbolUniqueId texture_USamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3857);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3858);
+ static constexpr const TSymbolUniqueId texture_ISampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3859);
+ static constexpr const TSymbolUniqueId texture_USampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3860);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3861);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3862);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3863);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3864);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3865);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3866);
+ static constexpr const TSymbolUniqueId textureProj_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3867);
+ static constexpr const TSymbolUniqueId textureProj_ISampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3868);
+ static constexpr const TSymbolUniqueId textureProj_USampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3869);
+ static constexpr const TSymbolUniqueId texture_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(3870);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeShadow1_Float4_Float1 =
+ TSymbolUniqueId(3871);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(3872);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3873);
+ static constexpr const TSymbolUniqueId texture_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3874);
+ static constexpr const TSymbolUniqueId texture_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3875);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3876);
+ static constexpr const TSymbolUniqueId textureExt_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3877);
+ static constexpr const TSymbolUniqueId textureExt_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3878);
+ static constexpr const TSymbolUniqueId texture_SamplerExternalOES1_Float2_Float1 =
+ TSymbolUniqueId(3879);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float3_Float1 =
+ TSymbolUniqueId(3880);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float4_Float1 =
+ TSymbolUniqueId(3881);
+ static constexpr const TSymbolUniqueId texture_SamplerExternal2DY2YEXT1_Float2_Float1 =
+ TSymbolUniqueId(3882);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float3_Float1 =
+ TSymbolUniqueId(3883);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float4_Float1 =
+ TSymbolUniqueId(3884);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2D1_Float2_Int2 =
+ TSymbolUniqueId(3885);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2D1_Float2_Int2 =
+ TSymbolUniqueId(3886);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2D1_Float2_Int2 =
+ TSymbolUniqueId(3887);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler3D1_Float3_Int3 =
+ TSymbolUniqueId(3888);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler3D1_Float3_Int3 =
+ TSymbolUniqueId(3889);
+ static constexpr const TSymbolUniqueId textureOffset_USampler3D1_Float3_Int3 =
+ TSymbolUniqueId(3890);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DShadow1_Float3_Int2 =
+ TSymbolUniqueId(3891);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(3892);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(3893);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(3894);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float3_Int2 =
+ TSymbolUniqueId(3895);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float3_Int2 =
+ TSymbolUniqueId(3896);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float3_Int2 =
+ TSymbolUniqueId(3897);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float4_Int2 =
+ TSymbolUniqueId(3898);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float4_Int2 =
+ TSymbolUniqueId(3899);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float4_Int2 =
+ TSymbolUniqueId(3900);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler3D1_Float4_Int3 =
+ TSymbolUniqueId(3901);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler3D1_Float4_Int3 =
+ TSymbolUniqueId(3902);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler3D1_Float4_Int3 =
+ TSymbolUniqueId(3903);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DShadow1_Float4_Int2 =
+ TSymbolUniqueId(3904);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(3905);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(3906);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(3907);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(3908);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(3909);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(3910);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2DShadow1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3911);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3912);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3913);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3914);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3915);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3916);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3917);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(3918);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(3919);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(3920);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(3921);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(3922);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(3923);
+ static constexpr const TSymbolUniqueId
+ textureProjLodOffset_Sampler2DShadow1_Float4_Float1_Int2 = TSymbolUniqueId(3924);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(3925);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(3926);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(3927);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(3928);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(3929);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(3930);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(3931);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(3932);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(3933);
+ static constexpr const TSymbolUniqueId textureGradOffset_Sampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(3934);
+ static constexpr const TSymbolUniqueId textureGradOffset_ISampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(3935);
+ static constexpr const TSymbolUniqueId textureGradOffset_USampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(3936);
+ static constexpr const TSymbolUniqueId textureGradOffset_Sampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(3937);
+ static constexpr const TSymbolUniqueId textureGradOffset_ISampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(3938);
+ static constexpr const TSymbolUniqueId textureGradOffset_USampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(3939);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DShadow1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3940);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3941);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_ISampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3942);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_USampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3943);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DArrayShadow1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(3944);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3945);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3946);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3947);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(3948);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(3949);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(3950);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(3951);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(3952);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(3953);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2DShadow1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(3954);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(3955);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(3956);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(3957);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(3958);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(3959);
+ static constexpr const TSymbolUniqueId textureOffset_USampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(3960);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DShadow1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3961);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3962);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3963);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3964);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3965);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3966);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3967);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(3968);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(3969);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(3970);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(3971);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(3972);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(3973);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DShadow1_Float4_Int2_Float1 =
+ TSymbolUniqueId(3974);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2D1_Float2 = TSymbolUniqueId(3975);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2D1_Float2 = TSymbolUniqueId(3976);
+ static constexpr const TSymbolUniqueId textureGather_USampler2D1_Float2 = TSymbolUniqueId(3977);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2D1_Float2_Int1 =
+ TSymbolUniqueId(3978);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2D1_Float2_Int1 =
+ TSymbolUniqueId(3979);
+ static constexpr const TSymbolUniqueId textureGather_USampler2D1_Float2_Int1 =
+ TSymbolUniqueId(3980);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArray1_Float3 =
+ TSymbolUniqueId(3981);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DArray1_Float3 =
+ TSymbolUniqueId(3982);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DArray1_Float3 =
+ TSymbolUniqueId(3983);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(3984);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(3985);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(3986);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCube1_Float3 =
+ TSymbolUniqueId(3987);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCube1_Float3 =
+ TSymbolUniqueId(3988);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCube1_Float3 =
+ TSymbolUniqueId(3989);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(3990);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(3991);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(3992);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3993);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3994);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3995);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(3996);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(3997);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(3998);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(3999);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(4000);
+ static constexpr const TSymbolUniqueId textureGatherExt_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(4001);
+ static constexpr const TSymbolUniqueId textureGatherExt_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(4002);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(4003);
+ static constexpr const TSymbolUniqueId textureGatherExt_ISamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(4004);
+ static constexpr const TSymbolUniqueId textureGatherExt_USamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(4005);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(4006);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DShadow1_Float2 =
+ TSymbolUniqueId(4007);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DShadow1_Float2_Float1 =
+ TSymbolUniqueId(4008);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArrayShadow1_Float3 =
+ TSymbolUniqueId(4009);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArrayShadow1_Float3_Float1 =
+ TSymbolUniqueId(4010);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeShadow1_Float3 =
+ TSymbolUniqueId(4011);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeShadow1_Float3_Float1 =
+ TSymbolUniqueId(4012);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2D1_Float2_Int2 =
+ TSymbolUniqueId(4013);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2D1_Float2_Int2 =
+ TSymbolUniqueId(4014);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2D1_Float2_Int2 =
+ TSymbolUniqueId(4015);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(4016);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(4017);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(4018);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DShadow1_Float2_Float1_Int2 =
+ TSymbolUniqueId(4019);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffset_Sampler2DArrayShadow1_Float3_Float1_Int2 = TSymbolUniqueId(4020);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(4021);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(4022);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(4023);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(4024);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(4025);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(4026);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4027);
+ static constexpr const TSymbolUniqueId pt10Dx4 = TSymbolUniqueId(4028);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4029);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4030);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4031);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4032);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4033);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_Sampler2DShadow1_Float2_Float1_4xInt2 = TSymbolUniqueId(4034);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_Sampler2DArrayShadow1_Float3_Float1_4xInt2 = TSymbolUniqueId(4035);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4036);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4037);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4038);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4039);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4040);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4041);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DShadow1_Float2_Float1_4xInt2 = TSymbolUniqueId(4042);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DArrayShadow1_Float3_Float1_4xInt2 = TSymbolUniqueId(4043);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4044);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4045);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4046);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DArray1_Float3_4xInt2_Int1 =
+ TSymbolUniqueId(4047);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_ISampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(4048);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_USampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(4049);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4050);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4051);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4052);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(4053);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(4054);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(4055);
+ static constexpr const TSymbolUniqueId rgb_2_yuv_Float3_YuvCscStandardEXT1 =
+ TSymbolUniqueId(4056);
+ static constexpr const TSymbolUniqueId pt00H = TSymbolUniqueId(4057);
+ static constexpr const TSymbolUniqueId yuv_2_rgb_Float3_YuvCscStandardEXT1 =
+ TSymbolUniqueId(4058);
+ static constexpr const TSymbolUniqueId dFdxExt_Float1 = TSymbolUniqueId(4059);
+ static constexpr const TSymbolUniqueId dFdxExt_Float2 = TSymbolUniqueId(4060);
+ static constexpr const TSymbolUniqueId dFdxExt_Float3 = TSymbolUniqueId(4061);
+ static constexpr const TSymbolUniqueId dFdxExt_Float4 = TSymbolUniqueId(4062);
+ static constexpr const TSymbolUniqueId dFdyExt_Float1 = TSymbolUniqueId(4063);
+ static constexpr const TSymbolUniqueId dFdyExt_Float2 = TSymbolUniqueId(4064);
+ static constexpr const TSymbolUniqueId dFdyExt_Float3 = TSymbolUniqueId(4065);
+ static constexpr const TSymbolUniqueId dFdyExt_Float4 = TSymbolUniqueId(4066);
+ static constexpr const TSymbolUniqueId fwidthExt_Float1 = TSymbolUniqueId(4067);
+ static constexpr const TSymbolUniqueId fwidthExt_Float2 = TSymbolUniqueId(4068);
+ static constexpr const TSymbolUniqueId fwidthExt_Float3 = TSymbolUniqueId(4069);
+ static constexpr const TSymbolUniqueId fwidthExt_Float4 = TSymbolUniqueId(4070);
+ static constexpr const TSymbolUniqueId dFdx_Float1 = TSymbolUniqueId(4071);
+ static constexpr const TSymbolUniqueId dFdx_Float2 = TSymbolUniqueId(4072);
+ static constexpr const TSymbolUniqueId dFdx_Float3 = TSymbolUniqueId(4073);
+ static constexpr const TSymbolUniqueId dFdx_Float4 = TSymbolUniqueId(4074);
+ static constexpr const TSymbolUniqueId dFdy_Float1 = TSymbolUniqueId(4075);
+ static constexpr const TSymbolUniqueId dFdy_Float2 = TSymbolUniqueId(4076);
+ static constexpr const TSymbolUniqueId dFdy_Float3 = TSymbolUniqueId(4077);
+ static constexpr const TSymbolUniqueId dFdy_Float4 = TSymbolUniqueId(4078);
+ static constexpr const TSymbolUniqueId fwidth_Float1 = TSymbolUniqueId(4079);
+ static constexpr const TSymbolUniqueId fwidth_Float2 = TSymbolUniqueId(4080);
+ static constexpr const TSymbolUniqueId fwidth_Float3 = TSymbolUniqueId(4081);
+ static constexpr const TSymbolUniqueId fwidth_Float4 = TSymbolUniqueId(4082);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float1 = TSymbolUniqueId(4083);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float2 = TSymbolUniqueId(4084);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float3 = TSymbolUniqueId(4085);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float4 = TSymbolUniqueId(4086);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float1_Int1 = TSymbolUniqueId(4087);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float2_Int1 = TSymbolUniqueId(4088);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float3_Int1 = TSymbolUniqueId(4089);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float4_Int1 = TSymbolUniqueId(4090);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float1_Float2 =
+ TSymbolUniqueId(4091);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float2_Float2 =
+ TSymbolUniqueId(4092);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float3_Float2 =
+ TSymbolUniqueId(4093);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float4_Float2 =
+ TSymbolUniqueId(4094);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float1 = TSymbolUniqueId(4095);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float2 = TSymbolUniqueId(4096);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float3 = TSymbolUniqueId(4097);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float4 = TSymbolUniqueId(4098);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float1_Int1 =
+ TSymbolUniqueId(4099);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float2_Int1 =
+ TSymbolUniqueId(4100);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float3_Int1 =
+ TSymbolUniqueId(4101);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float4_Int1 =
+ TSymbolUniqueId(4102);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float1_Float2 =
+ TSymbolUniqueId(4103);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float2_Float2 =
+ TSymbolUniqueId(4104);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float3_Float2 =
+ TSymbolUniqueId(4105);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float4_Float2 =
+ TSymbolUniqueId(4106);
+ static constexpr const TSymbolUniqueId atomicCounter_AtomicCounter1 = TSymbolUniqueId(4107);
+ static constexpr const TSymbolUniqueId pt00G = TSymbolUniqueId(4108);
+ static constexpr const TSymbolUniqueId atomicCounterIncrement_AtomicCounter1 =
+ TSymbolUniqueId(4109);
+ static constexpr const TSymbolUniqueId atomicCounterDecrement_AtomicCounter1 =
+ TSymbolUniqueId(4110);
+ static constexpr const TSymbolUniqueId atomicAdd_UInt1_UInt1 = TSymbolUniqueId(4111);
+ static constexpr const TSymbolUniqueId pt_io_00E = TSymbolUniqueId(4112);
+ static constexpr const TSymbolUniqueId atomicAdd_Int1_Int1 = TSymbolUniqueId(4113);
+ static constexpr const TSymbolUniqueId pt_io_00D = TSymbolUniqueId(4114);
+ static constexpr const TSymbolUniqueId atomicMin_UInt1_UInt1 = TSymbolUniqueId(4115);
+ static constexpr const TSymbolUniqueId atomicMin_Int1_Int1 = TSymbolUniqueId(4116);
+ static constexpr const TSymbolUniqueId atomicMax_UInt1_UInt1 = TSymbolUniqueId(4117);
+ static constexpr const TSymbolUniqueId atomicMax_Int1_Int1 = TSymbolUniqueId(4118);
+ static constexpr const TSymbolUniqueId atomicAnd_UInt1_UInt1 = TSymbolUniqueId(4119);
+ static constexpr const TSymbolUniqueId atomicAnd_Int1_Int1 = TSymbolUniqueId(4120);
+ static constexpr const TSymbolUniqueId atomicOr_UInt1_UInt1 = TSymbolUniqueId(4121);
+ static constexpr const TSymbolUniqueId atomicOr_Int1_Int1 = TSymbolUniqueId(4122);
+ static constexpr const TSymbolUniqueId atomicXor_UInt1_UInt1 = TSymbolUniqueId(4123);
+ static constexpr const TSymbolUniqueId atomicXor_Int1_Int1 = TSymbolUniqueId(4124);
+ static constexpr const TSymbolUniqueId atomicExchange_UInt1_UInt1 = TSymbolUniqueId(4125);
+ static constexpr const TSymbolUniqueId atomicExchange_Int1_Int1 = TSymbolUniqueId(4126);
+ static constexpr const TSymbolUniqueId atomicCompSwap_UInt1_UInt1_UInt1 = TSymbolUniqueId(4127);
+ static constexpr const TSymbolUniqueId atomicCompSwap_Int1_Int1_Int1 = TSymbolUniqueId(4128);
+ static constexpr const TSymbolUniqueId imageSize_Image2D1 = TSymbolUniqueId(4129);
+ static constexpr const TSymbolUniqueId pt00z = TSymbolUniqueId(4130);
+ static constexpr const TSymbolUniqueId imageSize_IImage2D1 = TSymbolUniqueId(4131);
+ static constexpr const TSymbolUniqueId pt01K = TSymbolUniqueId(4132);
+ static constexpr const TSymbolUniqueId imageSize_UImage2D1 = TSymbolUniqueId(4133);
+ static constexpr const TSymbolUniqueId pt01V = TSymbolUniqueId(4134);
+ static constexpr const TSymbolUniqueId imageSize_Image3D1 = TSymbolUniqueId(4135);
+ static constexpr const TSymbolUniqueId pt01A = TSymbolUniqueId(4136);
+ static constexpr const TSymbolUniqueId imageSize_IImage3D1 = TSymbolUniqueId(4137);
+ static constexpr const TSymbolUniqueId pt01L = TSymbolUniqueId(4138);
+ static constexpr const TSymbolUniqueId imageSize_UImage3D1 = TSymbolUniqueId(4139);
+ static constexpr const TSymbolUniqueId pt01W = TSymbolUniqueId(4140);
+ static constexpr const TSymbolUniqueId imageSize_Image2DArray1 = TSymbolUniqueId(4141);
+ static constexpr const TSymbolUniqueId pt01B = TSymbolUniqueId(4142);
+ static constexpr const TSymbolUniqueId imageSize_IImage2DArray1 = TSymbolUniqueId(4143);
+ static constexpr const TSymbolUniqueId pt01M = TSymbolUniqueId(4144);
+ static constexpr const TSymbolUniqueId imageSize_UImage2DArray1 = TSymbolUniqueId(4145);
+ static constexpr const TSymbolUniqueId pt01X = TSymbolUniqueId(4146);
+ static constexpr const TSymbolUniqueId imageSize_ImageCube1 = TSymbolUniqueId(4147);
+ static constexpr const TSymbolUniqueId pt01C = TSymbolUniqueId(4148);
+ static constexpr const TSymbolUniqueId imageSize_IImageCube1 = TSymbolUniqueId(4149);
+ static constexpr const TSymbolUniqueId pt01N = TSymbolUniqueId(4150);
+ static constexpr const TSymbolUniqueId imageSize_UImageCube1 = TSymbolUniqueId(4151);
+ static constexpr const TSymbolUniqueId pt01Y = TSymbolUniqueId(4152);
+ static constexpr const TSymbolUniqueId imageSize_ImageCubeArray1 = TSymbolUniqueId(4153);
+ static constexpr const TSymbolUniqueId pt01H = TSymbolUniqueId(4154);
+ static constexpr const TSymbolUniqueId imageSize_IImageCubeArray1 = TSymbolUniqueId(4155);
+ static constexpr const TSymbolUniqueId pt01S = TSymbolUniqueId(4156);
+ static constexpr const TSymbolUniqueId imageSize_UImageCubeArray1 = TSymbolUniqueId(4157);
+ static constexpr const TSymbolUniqueId pt01d = TSymbolUniqueId(4158);
+ static constexpr const TSymbolUniqueId imageSizeExt_ImageCubeArray1 = TSymbolUniqueId(4159);
+ static constexpr const TSymbolUniqueId imageSizeExt_IImageCubeArray1 = TSymbolUniqueId(4160);
+ static constexpr const TSymbolUniqueId imageSizeExt_UImageCubeArray1 = TSymbolUniqueId(4161);
+ static constexpr const TSymbolUniqueId imageSize_ImageBuffer1 = TSymbolUniqueId(4162);
+ static constexpr const TSymbolUniqueId pt01J = TSymbolUniqueId(4163);
+ static constexpr const TSymbolUniqueId imageSize_IImageBuffer1 = TSymbolUniqueId(4164);
+ static constexpr const TSymbolUniqueId pt01U = TSymbolUniqueId(4165);
+ static constexpr const TSymbolUniqueId imageSize_UImageBuffer1 = TSymbolUniqueId(4166);
+ static constexpr const TSymbolUniqueId pt01f = TSymbolUniqueId(4167);
+ static constexpr const TSymbolUniqueId imageSizeExt_ImageBuffer1 = TSymbolUniqueId(4168);
+ static constexpr const TSymbolUniqueId imageSizeExt_IImageBuffer1 = TSymbolUniqueId(4169);
+ static constexpr const TSymbolUniqueId imageSizeExt_UImageBuffer1 = TSymbolUniqueId(4170);
+ static constexpr const TSymbolUniqueId imageStore_Image2D1_Int2_Float4 = TSymbolUniqueId(4171);
+ static constexpr const TSymbolUniqueId imageStore_IImage2D1_Int2_Int4 = TSymbolUniqueId(4172);
+ static constexpr const TSymbolUniqueId imageStore_UImage2D1_Int2_UInt4 = TSymbolUniqueId(4173);
+ static constexpr const TSymbolUniqueId imageStore_Image3D1_Int3_Float4 = TSymbolUniqueId(4174);
+ static constexpr const TSymbolUniqueId imageStore_IImage3D1_Int3_Int4 = TSymbolUniqueId(4175);
+ static constexpr const TSymbolUniqueId imageStore_UImage3D1_Int3_UInt4 = TSymbolUniqueId(4176);
+ static constexpr const TSymbolUniqueId imageStore_Image2DArray1_Int3_Float4 =
+ TSymbolUniqueId(4177);
+ static constexpr const TSymbolUniqueId imageStore_IImage2DArray1_Int3_Int4 =
+ TSymbolUniqueId(4178);
+ static constexpr const TSymbolUniqueId imageStore_UImage2DArray1_Int3_UInt4 =
+ TSymbolUniqueId(4179);
+ static constexpr const TSymbolUniqueId imageStore_ImageCube1_Int3_Float4 =
+ TSymbolUniqueId(4180);
+ static constexpr const TSymbolUniqueId imageStore_IImageCube1_Int3_Int4 = TSymbolUniqueId(4181);
+ static constexpr const TSymbolUniqueId imageStore_UImageCube1_Int3_UInt4 =
+ TSymbolUniqueId(4182);
+ static constexpr const TSymbolUniqueId imageStore_ImageCubeArray1_Int3_Float4 =
+ TSymbolUniqueId(4183);
+ static constexpr const TSymbolUniqueId imageStore_IImageCubeArray1_Int3_Int4 =
+ TSymbolUniqueId(4184);
+ static constexpr const TSymbolUniqueId imageStore_UImageCubeArray1_Int3_UInt4 =
+ TSymbolUniqueId(4185);
+ static constexpr const TSymbolUniqueId imageStoreExt_ImageCubeArray1_Int3_Float4 =
+ TSymbolUniqueId(4186);
+ static constexpr const TSymbolUniqueId imageStoreExt_IImageCubeArray1_Int3_Int4 =
+ TSymbolUniqueId(4187);
+ static constexpr const TSymbolUniqueId imageStoreExt_UImageCubeArray1_Int3_UInt4 =
+ TSymbolUniqueId(4188);
+ static constexpr const TSymbolUniqueId imageStore_ImageBuffer1_Int1_Float4 =
+ TSymbolUniqueId(4189);
+ static constexpr const TSymbolUniqueId imageStore_IImageBuffer1_Int1_Int4 =
+ TSymbolUniqueId(4190);
+ static constexpr const TSymbolUniqueId imageStore_UImageBuffer1_Int1_UInt4 =
+ TSymbolUniqueId(4191);
+ static constexpr const TSymbolUniqueId imageStoreExt_ImageBuffer1_Int1_Float4 =
+ TSymbolUniqueId(4192);
+ static constexpr const TSymbolUniqueId imageStoreExt_IImageBuffer1_Int1_Int4 =
+ TSymbolUniqueId(4193);
+ static constexpr const TSymbolUniqueId imageStoreExt_UImageBuffer1_Int1_UInt4 =
+ TSymbolUniqueId(4194);
+ static constexpr const TSymbolUniqueId imageLoad_Image2D1_Int2 = TSymbolUniqueId(4195);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2D1_Int2 = TSymbolUniqueId(4196);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2D1_Int2 = TSymbolUniqueId(4197);
+ static constexpr const TSymbolUniqueId imageLoad_Image3D1_Int3 = TSymbolUniqueId(4198);
+ static constexpr const TSymbolUniqueId imageLoad_IImage3D1_Int3 = TSymbolUniqueId(4199);
+ static constexpr const TSymbolUniqueId imageLoad_UImage3D1_Int3 = TSymbolUniqueId(4200);
+ static constexpr const TSymbolUniqueId imageLoad_Image2DArray1_Int3 = TSymbolUniqueId(4201);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2DArray1_Int3 = TSymbolUniqueId(4202);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2DArray1_Int3 = TSymbolUniqueId(4203);
+ static constexpr const TSymbolUniqueId imageLoad_ImageCube1_Int3 = TSymbolUniqueId(4204);
+ static constexpr const TSymbolUniqueId imageLoad_IImageCube1_Int3 = TSymbolUniqueId(4205);
+ static constexpr const TSymbolUniqueId imageLoad_UImageCube1_Int3 = TSymbolUniqueId(4206);
+ static constexpr const TSymbolUniqueId imageLoad_ImageCubeArray1_Int3 = TSymbolUniqueId(4207);
+ static constexpr const TSymbolUniqueId imageLoad_IImageCubeArray1_Int3 = TSymbolUniqueId(4208);
+ static constexpr const TSymbolUniqueId imageLoad_UImageCubeArray1_Int3 = TSymbolUniqueId(4209);
+ static constexpr const TSymbolUniqueId imageLoadExt_ImageCubeArray1_Int3 =
+ TSymbolUniqueId(4210);
+ static constexpr const TSymbolUniqueId imageLoadExt_IImageCubeArray1_Int3 =
+ TSymbolUniqueId(4211);
+ static constexpr const TSymbolUniqueId imageLoadExt_UImageCubeArray1_Int3 =
+ TSymbolUniqueId(4212);
+ static constexpr const TSymbolUniqueId imageLoad_ImageBuffer1_Int1 = TSymbolUniqueId(4213);
+ static constexpr const TSymbolUniqueId imageLoad_IImageBuffer1_Int1 = TSymbolUniqueId(4214);
+ static constexpr const TSymbolUniqueId imageLoad_UImageBuffer1_Int1 = TSymbolUniqueId(4215);
+ static constexpr const TSymbolUniqueId imageLoadExt_ImageBuffer1_Int1 = TSymbolUniqueId(4216);
+ static constexpr const TSymbolUniqueId imageLoadExt_IImageBuffer1_Int1 = TSymbolUniqueId(4217);
+ static constexpr const TSymbolUniqueId imageLoadExt_UImageBuffer1_Int1 = TSymbolUniqueId(4218);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4219);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4220);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4221);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4222);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4223);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4224);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4225);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4226);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4227);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4228);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4229);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4230);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4231);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4232);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4233);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4234);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4235);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4236);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4237);
+ static constexpr const TSymbolUniqueId pt01D = TSymbolUniqueId(4238);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4239);
+ static constexpr const TSymbolUniqueId pt01O = TSymbolUniqueId(4240);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4241);
+ static constexpr const TSymbolUniqueId pt01Z = TSymbolUniqueId(4242);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4243);
+ static constexpr const TSymbolUniqueId pt01E = TSymbolUniqueId(4244);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4245);
+ static constexpr const TSymbolUniqueId pt01P = TSymbolUniqueId(4246);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4247);
+ static constexpr const TSymbolUniqueId pt01a = TSymbolUniqueId(4248);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4249);
+ static constexpr const TSymbolUniqueId pt01I = TSymbolUniqueId(4250);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4251);
+ static constexpr const TSymbolUniqueId pt01T = TSymbolUniqueId(4252);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4253);
+ static constexpr const TSymbolUniqueId pt01e = TSymbolUniqueId(4254);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4255);
+ static constexpr const TSymbolUniqueId pt01F = TSymbolUniqueId(4256);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4257);
+ static constexpr const TSymbolUniqueId pt01Q = TSymbolUniqueId(4258);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4259);
+ static constexpr const TSymbolUniqueId pt01b = TSymbolUniqueId(4260);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4261);
+ static constexpr const TSymbolUniqueId pt01G = TSymbolUniqueId(4262);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4263);
+ static constexpr const TSymbolUniqueId pt01R = TSymbolUniqueId(4264);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4265);
+ static constexpr const TSymbolUniqueId pt01c = TSymbolUniqueId(4266);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4267);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4268);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4269);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4270);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4271);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4272);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4273);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4274);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4275);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4276);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4277);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4278);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4279);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4280);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4281);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4282);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4283);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4284);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4285);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4286);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4287);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4288);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4289);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4290);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4291);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4292);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4293);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4294);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4295);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4296);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4297);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4298);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4299);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4300);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4301);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4302);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4303);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4304);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4305);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4306);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4307);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4308);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4309);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4310);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4311);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4312);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4313);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4314);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4315);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4316);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4317);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4318);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4319);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4320);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4321);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4322);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4323);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4324);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4325);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4326);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4327);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4328);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4329);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4330);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4331);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4332);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4333);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4334);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4335);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4336);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4337);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4338);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4339);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4340);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4341);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4342);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4343);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4344);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4345);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4346);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4347);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4348);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4349);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4350);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4351);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4352);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4353);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4354);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4355);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4356);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4357);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4358);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4359);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4360);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4361);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4362);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4363);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4364);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4365);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4366);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4367);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4368);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4369);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4370);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4371);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4372);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4373);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4374);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4375);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4376);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4377);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4378);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4379);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4380);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4381);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4382);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4383);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4384);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4385);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4386);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4387);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4388);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4389);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4390);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4391);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4392);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4393);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4394);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4395);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4396);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4397);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4398);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4399);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4400);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4401);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4402);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4403);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4404);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4405);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4406);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4407);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4408);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4409);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4410);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4411);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4412);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4413);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4414);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4415);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4416);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4417);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4418);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4419);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4420);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4421);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4422);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4423);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4424);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4425);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4426);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4427);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4428);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4429);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4430);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4431);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4432);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4433);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4434);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4435);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4436);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4437);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4438);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4439);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4440);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4441);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4442);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4443);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4444);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4445);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4446);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4447);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4448);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4449);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4450);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4451);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4452);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4453);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4454);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4455);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4456);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4457);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4458);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4459);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4460);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4461);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4462);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4463);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4464);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4465);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4466);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4467);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4468);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4469);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4470);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4471);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4472);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4473);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4474);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4475);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4476);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4477);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4478);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4479);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4480);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4481);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4482);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4483);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4484);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4485);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4486);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4487);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4488);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4489);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4490);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4491);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4492);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4493);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4494);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4495);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4496);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4497);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4498);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4499);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4500);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4501);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4502);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4503);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4504);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4505);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4506);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4507);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4508);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4509);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4510);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4511);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4512);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4513);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4514);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4515);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4516);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4517);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4518);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4519);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4520);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4521);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4522);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4523);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4524);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4525);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4526);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4527);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4528);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4529);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4530);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2D1_Int2_Int1 = TSymbolUniqueId(4531);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4532);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4533);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image3D1_Int3_Int1 = TSymbolUniqueId(4534);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4535);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4536);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4537);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4538);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4539);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4540);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4541);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4542);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4543);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4544);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4545);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4546);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4547);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4548);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1D1_Int1_Int1 = TSymbolUniqueId(4549);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4550);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4551);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4552);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4553);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4554);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4555);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4556);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4557);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4558);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4559);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4560);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4561);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4562);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4563);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4564);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4565);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4566);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4567);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4568);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4569);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4570);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4571);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4572);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4573);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4574);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4575);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4576);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4577);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4578);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4579);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4580);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4581);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4582);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4583);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4584);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4585);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4586);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4587);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4588);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4589);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4590);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4591);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4592);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4593);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4594);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4595);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4596);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4597);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4598);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4599);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4600);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4601);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4602);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4603);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4604);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4605);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4606);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4607);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4608);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4609);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4610);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4611);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4612);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4613);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4614);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4615);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4616);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4617);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4618);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4619);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4620);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4621);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4622);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4623);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4624);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4625);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4626);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4627);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4628);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4629);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4630);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4631);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4632);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4633);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4634);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4635);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4636);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4637);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4638);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4639);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4640);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4641);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4642);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4643);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4644);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4645);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4646);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4647);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4648);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4649);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4650);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4651);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4652);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4653);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4654);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4655);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4656);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4657);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4658);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4659);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4660);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4661);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4662);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4663);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4664);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4665);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4666);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4667);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4668);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4669);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4670);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4671);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4672);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4673);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4674);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4675);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4676);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4677);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4678);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4679);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4680);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4681);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4682);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4683);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4684);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4685);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4686);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4687);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4688);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4689);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4690);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4691);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4692);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4693);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4694);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4695);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_Float1 =
+ TSymbolUniqueId(4696);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_Float1 =
+ TSymbolUniqueId(4697);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_Float1 =
+ TSymbolUniqueId(4698);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_Float1 =
+ TSymbolUniqueId(4699);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_Float1 =
+ TSymbolUniqueId(4700);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_Float1 =
+ TSymbolUniqueId(4701);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_Float1 =
+ TSymbolUniqueId(4702);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_Float1 =
+ TSymbolUniqueId(4703);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_Float1 =
+ TSymbolUniqueId(4704);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(4705);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(4706);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(4707);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_Float1 =
+ TSymbolUniqueId(4708);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(4709);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(4710);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(4711);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(4712);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(4713);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_Float1 =
+ TSymbolUniqueId(4714);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_Float1 =
+ TSymbolUniqueId(4715);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_Float1 =
+ TSymbolUniqueId(4716);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_Float1 =
+ TSymbolUniqueId(4717);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(4718);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(4719);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_Float1 =
+ TSymbolUniqueId(4720);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_Float1 =
+ TSymbolUniqueId(4721);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_Float1 =
+ TSymbolUniqueId(4722);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(4723);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(4724);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(4725);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(4726);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(4727);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(4728);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4729);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4730);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4731);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4732);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4733);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4734);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4735);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4736);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4737);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4738);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4739);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4740);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4741);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4742);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4743);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4744);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4745);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4746);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4747);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4748);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4749);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4750);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4751);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4752);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4753);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4754);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4755);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4756);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4757);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4758);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(4759);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(4760);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(4761);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4762);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4763);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4764);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4765);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4766);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4767);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4768);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4769);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4770);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4771);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4772);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4773);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4774);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4775);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4776);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4777);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4778);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4779);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4780);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4781);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4782);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4783);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4784);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4785);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4786);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4787);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4788);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(4789);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(4790);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(4791);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_Int1_Int1 =
+ TSymbolUniqueId(4792);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(4793);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(4794);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4795);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4796);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4797);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4798);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4799);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4800);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4801);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4802);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4803);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4804);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4805);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4806);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4807);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4808);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4809);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4810);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4811);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4812);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4813);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4814);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4815);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4816);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4817);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4818);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4819);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4820);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4821);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4822);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4823);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4824);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4825);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4826);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4827);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4828);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4829);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4830);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4831);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4832);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4833);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4834);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4835);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4836);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4837);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4838);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4839);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4840);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4841);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4842);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4843);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4844);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4845);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4846);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4847);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4848);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4849);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4850);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4851);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4852);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4853);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4854);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4855);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4856);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4857);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4858);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4859);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4860);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4861);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4862);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4863);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4864);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4865);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4866);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4867);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4868);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4869);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4870);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4871);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4872);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4873);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4874);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4875);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4876);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4877);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4878);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4879);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4880);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4881);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4882);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4883);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4884);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4885);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4886);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4887);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4888);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4889);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4890);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4891);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4892);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4893);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4894);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4895);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4896);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4897);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4898);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4899);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4900);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4901);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4902);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4903);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4904);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4905);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4906);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4907);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4908);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4909);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4910);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4911);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4912);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4913);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4914);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4915);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4916);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4917);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4918);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4919);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4920);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4921);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4922);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4923);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4924);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4925);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4926);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4927);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4928);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4929);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4930);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4931);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4932);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4933);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4934);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4935);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4936);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4937);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4938);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4939);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4940);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4941);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4942);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4943);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4944);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4945);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4946);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4947);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4948);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4949);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4950);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4951);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4952);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4953);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4954);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4955);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4956);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4957);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4958);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4959);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4960);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4961);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4962);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4963);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4964);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4965);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4966);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4967);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4968);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4969);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4970);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4971);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4972);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4973);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4974);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4975);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4976);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4977);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4978);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4979);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4980);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4981);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4982);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4983);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4984);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4985);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4986);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4987);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4988);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4989);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4990);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4991);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4992);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4993);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4994);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4995);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4996);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4997);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4998);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4999);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5000);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5001);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5002);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5003);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5004);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5005);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5006);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5007);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5008);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5009);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5010);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(5011);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5012);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5013);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5014);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5015);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5016);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5017);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5018);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5019);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5020);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5021);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5022);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5023);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5024);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5025);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(5026);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5027);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5028);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(5029);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5030);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5031);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5032);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5033);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5034);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5035);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5036);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5037);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5038);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5039);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5040);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5041);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5042);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5043);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(5044);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5045);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5046);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5047);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5048);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5049);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5050);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5051);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5052);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5053);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5054);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5055);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5056);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5057);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5058);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(5059);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5060);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5061);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(5062);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5063);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5064);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5065);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5066);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5067);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5068);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5069);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5070);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5071);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5072);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5073);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5074);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5075);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5076);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(5077);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5078);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5079);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5080);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5081);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5082);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5083);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5084);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5085);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5086);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5087);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5088);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5089);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5090);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5091);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(5092);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5093);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5094);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(5095);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5096);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5097);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5098);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5099);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5100);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5101);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5102);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5103);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5104);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5105);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5106);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5107);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5108);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5109);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(5110);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5111);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5112);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5113);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5114);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5115);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5116);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5117);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5118);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5119);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5120);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5121);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5122);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5123);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5124);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(5125);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5126);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5127);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(5128);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5129);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5130);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5131);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5132);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5133);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5134);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5135);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5136);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5137);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5138);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5139);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5140);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5141);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5142);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(5143);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5144);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5145);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5146);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5147);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5148);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5149);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5150);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5151);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5152);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5153);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5154);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5155);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5156);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5157);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(5158);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5159);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5160);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(5161);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5162);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5163);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5164);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5165);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5166);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5167);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5168);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5169);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5170);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5171);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5172);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5173);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5174);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5175);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(5176);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5177);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5178);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5179);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5180);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5181);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5182);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5183);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5184);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5185);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5186);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5187);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5188);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5189);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5190);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(5191);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5192);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5193);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(5194);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5195);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5196);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5197);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5198);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5199);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5200);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5201);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5202);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5203);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5204);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5205);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5206);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5207);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5208);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(5209);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5210);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5211);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5212);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5213);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5214);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5215);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5216);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5217);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5218);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5219);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5220);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5221);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5222);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5223);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(5224);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5225);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5226);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(5227);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5228);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5229);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5230);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5231);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5232);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5233);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5234);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5235);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5236);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5237);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5238);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5239);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5240);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5241);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(5242);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5243);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5244);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5245);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5246);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5247);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5248);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5249);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5250);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5251);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5252);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5253);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5254);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5255);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5256);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_Float1 =
+ TSymbolUniqueId(5257);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_Float1 =
+ TSymbolUniqueId(5258);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_Float1 =
+ TSymbolUniqueId(5259);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_Float1 =
+ TSymbolUniqueId(5260);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_Float1 =
+ TSymbolUniqueId(5261);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_Float1 =
+ TSymbolUniqueId(5262);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_Float1 =
+ TSymbolUniqueId(5263);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_Float1 =
+ TSymbolUniqueId(5264);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_Float1 =
+ TSymbolUniqueId(5265);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(5266);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(5267);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(5268);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_Float1 =
+ TSymbolUniqueId(5269);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(5270);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(5271);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(5272);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(5273);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(5274);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_Float1 =
+ TSymbolUniqueId(5275);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_Float1 =
+ TSymbolUniqueId(5276);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_Float1 =
+ TSymbolUniqueId(5277);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_Float1 =
+ TSymbolUniqueId(5278);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(5279);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(5280);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_Float1 =
+ TSymbolUniqueId(5281);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_Float1 =
+ TSymbolUniqueId(5282);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_Float1 =
+ TSymbolUniqueId(5283);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(5284);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(5285);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(5286);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(5287);
+ static constexpr const TSymbolUniqueId
+ imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Float1 = TSymbolUniqueId(5288);
+ static constexpr const TSymbolUniqueId
+ imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Float1 = TSymbolUniqueId(5289);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5290);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5291);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5292);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5293);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5294);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5295);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5296);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5297);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5298);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5299);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5300);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5301);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5302);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5303);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5304);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5305);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImageCubeArray1_Int3_UInt1_UInt1 = TSymbolUniqueId(5306);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImageCubeArray1_Int3_UInt1_UInt1 = TSymbolUniqueId(5307);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5308);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5309);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5310);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5311);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5312);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5313);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5314);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5315);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5316);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5317);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_UInt1_UInt1 = TSymbolUniqueId(5318);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_UInt1_UInt1 = TSymbolUniqueId(5319);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(5320);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(5321);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(5322);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5323);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5324);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5325);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5326);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5327);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5328);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5329);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5330);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5331);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5332);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5333);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5334);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5335);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5336);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5337);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5338);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5339);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5340);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5341);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5342);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5343);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5344);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5345);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5346);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5347);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5348);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5349);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(5350);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(5351);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(5352);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(5353);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(5354);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(5355);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_PixelLocalANGLE1 =
+ TSymbolUniqueId(5356);
+ static constexpr const TSymbolUniqueId pt01g = TSymbolUniqueId(5357);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_IPixelLocalANGLE1 =
+ TSymbolUniqueId(5358);
+ static constexpr const TSymbolUniqueId pt01h = TSymbolUniqueId(5359);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_UPixelLocalANGLE1 =
+ TSymbolUniqueId(5360);
+ static constexpr const TSymbolUniqueId pt01i = TSymbolUniqueId(5361);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_PixelLocalANGLE1_Float4 =
+ TSymbolUniqueId(5362);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_IPixelLocalANGLE1_Int4 =
+ TSymbolUniqueId(5363);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_UPixelLocalANGLE1_UInt4 =
+ TSymbolUniqueId(5364);
+ static constexpr const TSymbolUniqueId beginInvocationInterlockNV = TSymbolUniqueId(5365);
+ static constexpr const TSymbolUniqueId endInvocationInterlockNV = TSymbolUniqueId(5366);
+ static constexpr const TSymbolUniqueId beginFragmentShaderOrderingINTEL = TSymbolUniqueId(5367);
+ static constexpr const TSymbolUniqueId beginInvocationInterlockARB = TSymbolUniqueId(5368);
+ static constexpr const TSymbolUniqueId endInvocationInterlockARB = TSymbolUniqueId(5369);
+ static constexpr const TSymbolUniqueId memoryBarrier = TSymbolUniqueId(5370);
+ static constexpr const TSymbolUniqueId memoryBarrierAtomicCounter = TSymbolUniqueId(5371);
+ static constexpr const TSymbolUniqueId memoryBarrierBuffer = TSymbolUniqueId(5372);
+ static constexpr const TSymbolUniqueId memoryBarrierImage = TSymbolUniqueId(5373);
+ static constexpr const TSymbolUniqueId barrier = TSymbolUniqueId(5374);
+ static constexpr const TSymbolUniqueId memoryBarrierShared = TSymbolUniqueId(5375);
+ static constexpr const TSymbolUniqueId groupMemoryBarrier = TSymbolUniqueId(5376);
+ static constexpr const TSymbolUniqueId barrierTCS = TSymbolUniqueId(5377);
+ static constexpr const TSymbolUniqueId barrierTCSES3_2 = TSymbolUniqueId(5378);
+ static constexpr const TSymbolUniqueId EmitVertex = TSymbolUniqueId(5379);
+ static constexpr const TSymbolUniqueId EmitVertexES3_2 = TSymbolUniqueId(5380);
+ static constexpr const TSymbolUniqueId EndPrimitive = TSymbolUniqueId(5381);
+ static constexpr const TSymbolUniqueId EndPrimitiveES3_2 = TSymbolUniqueId(5382);
+ static constexpr const TSymbolUniqueId subpassLoad_SubpassInput1 = TSymbolUniqueId(5383);
+ static constexpr const TSymbolUniqueId pt01j = TSymbolUniqueId(5384);
+ static constexpr const TSymbolUniqueId subpassLoad_ISubpassInput1 = TSymbolUniqueId(5385);
+ static constexpr const TSymbolUniqueId pt01k = TSymbolUniqueId(5386);
+ static constexpr const TSymbolUniqueId subpassLoad_USubpassInput1 = TSymbolUniqueId(5387);
+ static constexpr const TSymbolUniqueId pt01l = TSymbolUniqueId(5388);
+ static constexpr const TSymbolUniqueId subpassLoad_SubpassInputMS1_Int1 = TSymbolUniqueId(5389);
+ static constexpr const TSymbolUniqueId pt01m = TSymbolUniqueId(5390);
+ static constexpr const TSymbolUniqueId subpassLoad_ISubpassInputMS1_Int1 =
+ TSymbolUniqueId(5391);
+ static constexpr const TSymbolUniqueId pt01n = TSymbolUniqueId(5392);
+ static constexpr const TSymbolUniqueId subpassLoad_USubpassInputMS1_Int1 =
+ TSymbolUniqueId(5393);
+ static constexpr const TSymbolUniqueId pt01o = TSymbolUniqueId(5394);
+ static constexpr const TSymbolUniqueId gl_DepthRangeParameters = TSymbolUniqueId(5395);
+ static constexpr const TSymbolUniqueId gl_DepthRange = TSymbolUniqueId(5396);
+ static constexpr const TSymbolUniqueId gl_NumSamples = TSymbolUniqueId(5397);
+ static constexpr const TSymbolUniqueId gl_NumSamplesES3_2 = TSymbolUniqueId(5398);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAttribs = TSymbolUniqueId(5399);
+ static constexpr const TSymbolUniqueId gl_MaxVertexUniformVectors = TSymbolUniqueId(5400);
+ static constexpr const TSymbolUniqueId gl_MaxVertexTextureImageUnits = TSymbolUniqueId(5401);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedTextureImageUnits = TSymbolUniqueId(5402);
+ static constexpr const TSymbolUniqueId gl_MaxTextureImageUnits = TSymbolUniqueId(5403);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentUniformVectors = TSymbolUniqueId(5404);
+ static constexpr const TSymbolUniqueId gl_MaxVaryingVectors = TSymbolUniqueId(5405);
+ static constexpr const TSymbolUniqueId gl_MaxDrawBuffers = TSymbolUniqueId(5406);
+ static constexpr const TSymbolUniqueId gl_MaxDualSourceDrawBuffersEXT = TSymbolUniqueId(5407);
+ static constexpr const TSymbolUniqueId gl_MaxVertexOutputVectors = TSymbolUniqueId(5408);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentInputVectors = TSymbolUniqueId(5409);
+ static constexpr const TSymbolUniqueId gl_MinProgramTexelOffset = TSymbolUniqueId(5410);
+ static constexpr const TSymbolUniqueId gl_MaxProgramTexelOffset = TSymbolUniqueId(5411);
+ static constexpr const TSymbolUniqueId gl_MaxImageUnits = TSymbolUniqueId(5412);
+ static constexpr const TSymbolUniqueId gl_MaxVertexImageUniforms = TSymbolUniqueId(5413);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentImageUniforms = TSymbolUniqueId(5414);
+ static constexpr const TSymbolUniqueId gl_MaxComputeImageUniforms = TSymbolUniqueId(5415);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedImageUniforms = TSymbolUniqueId(5416);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedShaderOutputResources =
+ TSymbolUniqueId(5417);
+ static constexpr const TSymbolUniqueId gl_MaxComputeWorkGroupCount = TSymbolUniqueId(5418);
+ static constexpr const TSymbolUniqueId gl_MaxComputeWorkGroupSize = TSymbolUniqueId(5419);
+ static constexpr const TSymbolUniqueId gl_MaxComputeUniformComponents = TSymbolUniqueId(5420);
+ static constexpr const TSymbolUniqueId gl_MaxComputeTextureImageUnits = TSymbolUniqueId(5421);
+ static constexpr const TSymbolUniqueId gl_MaxComputeAtomicCounters = TSymbolUniqueId(5422);
+ static constexpr const TSymbolUniqueId gl_MaxComputeAtomicCounterBuffers =
+ TSymbolUniqueId(5423);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAtomicCounters = TSymbolUniqueId(5424);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentAtomicCounters = TSymbolUniqueId(5425);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedAtomicCounters = TSymbolUniqueId(5426);
+ static constexpr const TSymbolUniqueId gl_MaxAtomicCounterBindings = TSymbolUniqueId(5427);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAtomicCounterBuffers = TSymbolUniqueId(5428);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentAtomicCounterBuffers =
+ TSymbolUniqueId(5429);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedAtomicCounterBuffers =
+ TSymbolUniqueId(5430);
+ static constexpr const TSymbolUniqueId gl_MaxAtomicCounterBufferSize = TSymbolUniqueId(5431);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryInputComponents = TSymbolUniqueId(5432);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryInputComponentsES3_2 =
+ TSymbolUniqueId(5433);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputComponents = TSymbolUniqueId(5434);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputComponentsES3_2 =
+ TSymbolUniqueId(5435);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryImageUniforms = TSymbolUniqueId(5436);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryImageUniformsES3_2 = TSymbolUniqueId(5437);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTextureImageUnits = TSymbolUniqueId(5438);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTextureImageUnitsES3_2 =
+ TSymbolUniqueId(5439);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputVertices = TSymbolUniqueId(5440);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputVerticesES3_2 =
+ TSymbolUniqueId(5441);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTotalOutputComponents =
+ TSymbolUniqueId(5442);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTotalOutputComponentsES3_2 =
+ TSymbolUniqueId(5443);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryUniformComponents = TSymbolUniqueId(5444);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryUniformComponentsES3_2 =
+ TSymbolUniqueId(5445);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounters = TSymbolUniqueId(5446);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCountersES3_2 =
+ TSymbolUniqueId(5447);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounterBuffers =
+ TSymbolUniqueId(5448);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(5449);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlInputComponents = TSymbolUniqueId(5450);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlInputComponentsES3_2 =
+ TSymbolUniqueId(5451);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlOutputComponents =
+ TSymbolUniqueId(5452);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlOutputComponentsES3_2 =
+ TSymbolUniqueId(5453);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTextureImageUnits =
+ TSymbolUniqueId(5454);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTextureImageUnitsES3_2 =
+ TSymbolUniqueId(5455);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlUniformComponents =
+ TSymbolUniqueId(5456);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlUniformComponentsES3_2 =
+ TSymbolUniqueId(5457);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTotalOutputComponents =
+ TSymbolUniqueId(5458);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTotalOutputComponentsES3_2 =
+ TSymbolUniqueId(5459);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlImageUniforms = TSymbolUniqueId(5460);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlImageUniformsES3_2 =
+ TSymbolUniqueId(5461);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounters = TSymbolUniqueId(5462);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCountersES3_2 =
+ TSymbolUniqueId(5463);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounterBuffers =
+ TSymbolUniqueId(5464);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(5465);
+ static constexpr const TSymbolUniqueId gl_MaxTessPatchComponents = TSymbolUniqueId(5466);
+ static constexpr const TSymbolUniqueId gl_MaxTessPatchComponentsES3_2 = TSymbolUniqueId(5467);
+ static constexpr const TSymbolUniqueId gl_MaxPatchVertices = TSymbolUniqueId(5468);
+ static constexpr const TSymbolUniqueId gl_MaxPatchVerticesES3_2 = TSymbolUniqueId(5469);
+ static constexpr const TSymbolUniqueId gl_MaxTessGenLevel = TSymbolUniqueId(5470);
+ static constexpr const TSymbolUniqueId gl_MaxTessGenLevelES3_2 = TSymbolUniqueId(5471);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationInputComponents =
+ TSymbolUniqueId(5472);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationInputComponentsES3_2 =
+ TSymbolUniqueId(5473);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationOutputComponents =
+ TSymbolUniqueId(5474);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationOutputComponentsES3_2 =
+ TSymbolUniqueId(5475);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationTextureImageUnits =
+ TSymbolUniqueId(5476);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationTextureImageUnitsES3_2 =
+ TSymbolUniqueId(5477);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationUniformComponents =
+ TSymbolUniqueId(5478);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationUniformComponentsES3_2 =
+ TSymbolUniqueId(5479);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationImageUniforms =
+ TSymbolUniqueId(5480);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationImageUniformsES3_2 =
+ TSymbolUniqueId(5481);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounters =
+ TSymbolUniqueId(5482);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCountersES3_2 =
+ TSymbolUniqueId(5483);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounterBuffers =
+ TSymbolUniqueId(5484);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(5485);
+ static constexpr const TSymbolUniqueId gl_MaxSamples = TSymbolUniqueId(5486);
+ static constexpr const TSymbolUniqueId gl_MaxSamplesES3_2 = TSymbolUniqueId(5487);
+ static constexpr const TSymbolUniqueId gl_MaxClipDistancesAPPLE = TSymbolUniqueId(5488);
+ static constexpr const TSymbolUniqueId gl_MaxCullDistancesEXT = TSymbolUniqueId(5489);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedClipAndCullDistancesEXT =
+ TSymbolUniqueId(5490);
+ static constexpr const TSymbolUniqueId gl_FragCoord = TSymbolUniqueId(5491);
+ static constexpr const TSymbolUniqueId gl_FrontFacing = TSymbolUniqueId(5492);
+ static constexpr const TSymbolUniqueId gl_PointCoord = TSymbolUniqueId(5493);
+ static constexpr const TSymbolUniqueId gl_FragColor = TSymbolUniqueId(5494);
+ static constexpr const TSymbolUniqueId gl_FragData = TSymbolUniqueId(5495);
+ static constexpr const TSymbolUniqueId gl_FragDepth = TSymbolUniqueId(5496);
+ static constexpr const TSymbolUniqueId gl_HelperInvocation = TSymbolUniqueId(5497);
+ static constexpr const TSymbolUniqueId gl_FragCoord300 = TSymbolUniqueId(5498);
+ static constexpr const TSymbolUniqueId gl_SecondaryFragColorEXT = TSymbolUniqueId(5499);
+ static constexpr const TSymbolUniqueId gl_SecondaryFragDataEXT = TSymbolUniqueId(5500);
+ static constexpr const TSymbolUniqueId gl_FragDepthEXT = TSymbolUniqueId(5501);
+ static constexpr const TSymbolUniqueId gl_LastFragData = TSymbolUniqueId(5502);
+ static constexpr const TSymbolUniqueId gl_LastFragColor = TSymbolUniqueId(5503);
+ static constexpr const TSymbolUniqueId gl_LastFragDataNV = TSymbolUniqueId(5504);
+ static constexpr const TSymbolUniqueId gl_LastFragColorARM = TSymbolUniqueId(5505);
+ static constexpr const TSymbolUniqueId gl_PrimitiveID = TSymbolUniqueId(5506);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDES3_2 = TSymbolUniqueId(5507);
+ static constexpr const TSymbolUniqueId gl_Layer = TSymbolUniqueId(5508);
+ static constexpr const TSymbolUniqueId gl_LayerES3_2 = TSymbolUniqueId(5509);
+ static constexpr const TSymbolUniqueId gl_SampleID = TSymbolUniqueId(5510);
+ static constexpr const TSymbolUniqueId gl_SampleIDES3_2 = TSymbolUniqueId(5511);
+ static constexpr const TSymbolUniqueId gl_SamplePosition = TSymbolUniqueId(5512);
+ static constexpr const TSymbolUniqueId gl_SamplePositionES3_2 = TSymbolUniqueId(5513);
+ static constexpr const TSymbolUniqueId gl_SampleMaskIn = TSymbolUniqueId(5514);
+ static constexpr const TSymbolUniqueId gl_SampleMaskInES3_2 = TSymbolUniqueId(5515);
+ static constexpr const TSymbolUniqueId gl_SampleMask = TSymbolUniqueId(5516);
+ static constexpr const TSymbolUniqueId gl_SampleMaskES3_2 = TSymbolUniqueId(5517);
+ static constexpr const TSymbolUniqueId gl_CullDistance = TSymbolUniqueId(5518);
+ static constexpr const TSymbolUniqueId gl_ClipDistance = TSymbolUniqueId(5519);
+ static constexpr const TSymbolUniqueId gl_Position = TSymbolUniqueId(5520);
+ static constexpr const TSymbolUniqueId gl_PointSize = TSymbolUniqueId(5521);
+ static constexpr const TSymbolUniqueId gl_InstanceID = TSymbolUniqueId(5522);
+ static constexpr const TSymbolUniqueId gl_InstanceIndex = TSymbolUniqueId(5523);
+ static constexpr const TSymbolUniqueId gl_VertexID = TSymbolUniqueId(5524);
+ static constexpr const TSymbolUniqueId gl_VertexIndex = TSymbolUniqueId(5525);
+ static constexpr const TSymbolUniqueId gl_ViewportIndex = TSymbolUniqueId(5526);
+ static constexpr const TSymbolUniqueId gl_LayerVS = TSymbolUniqueId(5527);
+ static constexpr const TSymbolUniqueId gl_PointSize300 = TSymbolUniqueId(5528);
+ static constexpr const TSymbolUniqueId gl_DrawID = TSymbolUniqueId(5529);
+ static constexpr const TSymbolUniqueId gl_BaseVertex = TSymbolUniqueId(5530);
+ static constexpr const TSymbolUniqueId gl_BaseInstance = TSymbolUniqueId(5531);
+ static constexpr const TSymbolUniqueId angle_BaseVertex = TSymbolUniqueId(5532);
+ static constexpr const TSymbolUniqueId angle_BaseInstance = TSymbolUniqueId(5533);
+ static constexpr const TSymbolUniqueId gl_ClipDistanceAPPLE = TSymbolUniqueId(5534);
+ static constexpr const TSymbolUniqueId gl_CullDistanceEXT = TSymbolUniqueId(5535);
+ static constexpr const TSymbolUniqueId gl_NumWorkGroups = TSymbolUniqueId(5536);
+ static constexpr const TSymbolUniqueId gl_WorkGroupSize = TSymbolUniqueId(5537);
+ static constexpr const TSymbolUniqueId gl_WorkGroupID = TSymbolUniqueId(5538);
+ static constexpr const TSymbolUniqueId gl_LocalInvocationID = TSymbolUniqueId(5539);
+ static constexpr const TSymbolUniqueId gl_GlobalInvocationID = TSymbolUniqueId(5540);
+ static constexpr const TSymbolUniqueId gl_LocalInvocationIndex = TSymbolUniqueId(5541);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDIn = TSymbolUniqueId(5542);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDInES3_2 = TSymbolUniqueId(5543);
+ static constexpr const TSymbolUniqueId gl_InvocationID = TSymbolUniqueId(5544);
+ static constexpr const TSymbolUniqueId gl_InvocationIDES3_2 = TSymbolUniqueId(5545);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDGS = TSymbolUniqueId(5546);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDGSES3_2 = TSymbolUniqueId(5547);
+ static constexpr const TSymbolUniqueId gl_LayerGS = TSymbolUniqueId(5548);
+ static constexpr const TSymbolUniqueId gl_LayerGSES3_2 = TSymbolUniqueId(5549);
+ static constexpr const TSymbolUniqueId gl_PerVertex = TSymbolUniqueId(5550);
+ static constexpr const TSymbolUniqueId gl_PerVertexES3_2 = TSymbolUniqueId(5551);
+ static constexpr const TSymbolUniqueId gl_in = TSymbolUniqueId(5552);
+ static constexpr const TSymbolUniqueId gl_inES3_2 = TSymbolUniqueId(5553);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutBlock = TSymbolUniqueId(5554);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutBlockES3_2 = TSymbolUniqueId(5555);
+ static constexpr const TSymbolUniqueId gl_PositionGS = TSymbolUniqueId(5556);
+ static constexpr const TSymbolUniqueId gl_PositionGSES3_2 = TSymbolUniqueId(5557);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTCS = TSymbolUniqueId(5558);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTCSES3_2 = TSymbolUniqueId(5559);
+ static constexpr const TSymbolUniqueId gl_InvocationIDTCS = TSymbolUniqueId(5560);
+ static constexpr const TSymbolUniqueId gl_InvocationIDTCSES3_2 = TSymbolUniqueId(5561);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTCS = TSymbolUniqueId(5562);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTCSES3_2 = TSymbolUniqueId(5563);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTCS = TSymbolUniqueId(5564);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTCSES3_2 = TSymbolUniqueId(5565);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTCS = TSymbolUniqueId(5566);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTCSES3_2 = TSymbolUniqueId(5567);
+ static constexpr const TSymbolUniqueId gl_PerVertexTCS = TSymbolUniqueId(5568);
+ static constexpr const TSymbolUniqueId gl_PerVertexTCSES3_2 = TSymbolUniqueId(5569);
+ static constexpr const TSymbolUniqueId gl_inTCS = TSymbolUniqueId(5570);
+ static constexpr const TSymbolUniqueId gl_inTCSES3_2 = TSymbolUniqueId(5571);
+ static constexpr const TSymbolUniqueId gl_outTCS = TSymbolUniqueId(5572);
+ static constexpr const TSymbolUniqueId gl_outTCSES3_2 = TSymbolUniqueId(5573);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxTCS = TSymbolUniqueId(5574);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxTCSES3_2 = TSymbolUniqueId(5575);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTcsBlock = TSymbolUniqueId(5576);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTcsBlockES3_2 = TSymbolUniqueId(5577);
+ static constexpr const TSymbolUniqueId gl_PositionTCS = TSymbolUniqueId(5578);
+ static constexpr const TSymbolUniqueId gl_PositionTCSES3_2 = TSymbolUniqueId(5579);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxEXTTCS = TSymbolUniqueId(5580);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxEXTTCSES3_2 = TSymbolUniqueId(5581);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxOESTCS = TSymbolUniqueId(5582);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxOESTCSES3_2 = TSymbolUniqueId(5583);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTES = TSymbolUniqueId(5584);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTESES3_2 = TSymbolUniqueId(5585);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTES = TSymbolUniqueId(5586);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTESES3_2 = TSymbolUniqueId(5587);
+ static constexpr const TSymbolUniqueId gl_TessCoord = TSymbolUniqueId(5588);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTES = TSymbolUniqueId(5589);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTESES3_2 = TSymbolUniqueId(5590);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTES = TSymbolUniqueId(5591);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTESES3_2 = TSymbolUniqueId(5592);
+ static constexpr const TSymbolUniqueId gl_PerVertexTES = TSymbolUniqueId(5593);
+ static constexpr const TSymbolUniqueId gl_PerVertexTESES3_2 = TSymbolUniqueId(5594);
+ static constexpr const TSymbolUniqueId gl_inTES = TSymbolUniqueId(5595);
+ static constexpr const TSymbolUniqueId gl_inTESES3_2 = TSymbolUniqueId(5596);
+ static constexpr const TSymbolUniqueId gl_outTES = TSymbolUniqueId(5597);
+ static constexpr const TSymbolUniqueId gl_outTESES3_2 = TSymbolUniqueId(5598);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTesBlock = TSymbolUniqueId(5599);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTesBlockES3_2 = TSymbolUniqueId(5600);
+ static constexpr const TSymbolUniqueId gl_PositionTES = TSymbolUniqueId(5601);
+ static constexpr const TSymbolUniqueId gl_PositionTESES3_2 = TSymbolUniqueId(5602);
+ static constexpr const TSymbolUniqueId gl_ViewID_OVR = TSymbolUniqueId(5603);
+
+}; // class BuiltInId
+
+namespace BuiltInVariable
+{
+
+const TVariable *angle_BaseInstance();
+const TVariable *angle_BaseVertex();
+const TVariable *gl_BaseInstance();
+const TVariable *gl_BaseVertex();
+const TVariable *gl_DrawID();
+const TVariable *gl_FragColor();
+const TVariable *gl_FragCoord();
+const TVariable *gl_FragCoord300();
+const TVariable *gl_FragDepth();
+const TVariable *gl_FrontFacing();
+const TVariable *gl_GlobalInvocationID();
+const TVariable *gl_HelperInvocation();
+const TVariable *gl_InstanceID();
+const TVariable *gl_InstanceIndex();
+const TVariable *gl_InvocationID();
+const TVariable *gl_InvocationIDES3_2();
+const TVariable *gl_InvocationIDTCS();
+const TVariable *gl_InvocationIDTCSES3_2();
+const TVariable *gl_LastFragColor();
+const TVariable *gl_LastFragColorARM();
+const TVariable *gl_Layer();
+const TVariable *gl_LayerES3_2();
+const TVariable *gl_LayerGS();
+const TVariable *gl_LayerGSES3_2();
+const TVariable *gl_LayerVS();
+const TVariable *gl_LocalInvocationID();
+const TVariable *gl_LocalInvocationIndex();
+const TVariable *gl_NumSamples();
+const TVariable *gl_NumSamplesES3_2();
+const TVariable *gl_NumWorkGroups();
+const TVariable *gl_PatchVerticesInTCS();
+const TVariable *gl_PatchVerticesInTCSES3_2();
+const TVariable *gl_PatchVerticesInTES();
+const TVariable *gl_PatchVerticesInTESES3_2();
+const TVariable *gl_PointCoord();
+const TVariable *gl_PointSize();
+const TVariable *gl_PointSize300();
+const TVariable *gl_Position();
+const TVariable *gl_PrimitiveID();
+const TVariable *gl_PrimitiveIDES3_2();
+const TVariable *gl_PrimitiveIDGS();
+const TVariable *gl_PrimitiveIDGSES3_2();
+const TVariable *gl_PrimitiveIDIn();
+const TVariable *gl_PrimitiveIDInES3_2();
+const TVariable *gl_PrimitiveIDTCS();
+const TVariable *gl_PrimitiveIDTCSES3_2();
+const TVariable *gl_PrimitiveIDTES();
+const TVariable *gl_PrimitiveIDTESES3_2();
+const TVariable *gl_SampleID();
+const TVariable *gl_SampleIDES3_2();
+const TVariable *gl_SamplePosition();
+const TVariable *gl_SamplePositionES3_2();
+const TVariable *gl_SecondaryFragColorEXT();
+const TVariable *gl_TessCoord();
+const TVariable *gl_VertexID();
+const TVariable *gl_VertexIndex();
+const TVariable *gl_ViewID_OVR();
+const TVariable *gl_ViewportIndex();
+const TVariable *gl_WorkGroupID();
+const TVariable *gl_WorkGroupSize();
+
+} // namespace BuiltInVariable
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_complete_autogen.h b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_complete_autogen.h
new file mode 100644
index 0000000000..406d930d56
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_complete_autogen.h
@@ -0,0 +1,5008 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// BuiltIn_complete_autogen.h:
+// Compile-time initialized built-ins.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
+
+#include "compiler/translator/SymbolUniqueId.h"
+
+namespace sh
+{
+
+class TVariable;
+
+class BuiltInId
+{
+ public:
+ static constexpr const TSymbolUniqueId radians_Float1 = TSymbolUniqueId(0);
+ static constexpr const TSymbolUniqueId pt00B = TSymbolUniqueId(1);
+ static constexpr const TSymbolUniqueId radians_Float2 = TSymbolUniqueId(2);
+ static constexpr const TSymbolUniqueId pt10B = TSymbolUniqueId(3);
+ static constexpr const TSymbolUniqueId radians_Float3 = TSymbolUniqueId(4);
+ static constexpr const TSymbolUniqueId pt20B = TSymbolUniqueId(5);
+ static constexpr const TSymbolUniqueId radians_Float4 = TSymbolUniqueId(6);
+ static constexpr const TSymbolUniqueId pt30B = TSymbolUniqueId(7);
+ static constexpr const TSymbolUniqueId degrees_Float1 = TSymbolUniqueId(8);
+ static constexpr const TSymbolUniqueId degrees_Float2 = TSymbolUniqueId(9);
+ static constexpr const TSymbolUniqueId degrees_Float3 = TSymbolUniqueId(10);
+ static constexpr const TSymbolUniqueId degrees_Float4 = TSymbolUniqueId(11);
+ static constexpr const TSymbolUniqueId sin_Float1 = TSymbolUniqueId(12);
+ static constexpr const TSymbolUniqueId sin_Float2 = TSymbolUniqueId(13);
+ static constexpr const TSymbolUniqueId sin_Float3 = TSymbolUniqueId(14);
+ static constexpr const TSymbolUniqueId sin_Float4 = TSymbolUniqueId(15);
+ static constexpr const TSymbolUniqueId cos_Float1 = TSymbolUniqueId(16);
+ static constexpr const TSymbolUniqueId cos_Float2 = TSymbolUniqueId(17);
+ static constexpr const TSymbolUniqueId cos_Float3 = TSymbolUniqueId(18);
+ static constexpr const TSymbolUniqueId cos_Float4 = TSymbolUniqueId(19);
+ static constexpr const TSymbolUniqueId tan_Float1 = TSymbolUniqueId(20);
+ static constexpr const TSymbolUniqueId tan_Float2 = TSymbolUniqueId(21);
+ static constexpr const TSymbolUniqueId tan_Float3 = TSymbolUniqueId(22);
+ static constexpr const TSymbolUniqueId tan_Float4 = TSymbolUniqueId(23);
+ static constexpr const TSymbolUniqueId asin_Float1 = TSymbolUniqueId(24);
+ static constexpr const TSymbolUniqueId asin_Float2 = TSymbolUniqueId(25);
+ static constexpr const TSymbolUniqueId asin_Float3 = TSymbolUniqueId(26);
+ static constexpr const TSymbolUniqueId asin_Float4 = TSymbolUniqueId(27);
+ static constexpr const TSymbolUniqueId acos_Float1 = TSymbolUniqueId(28);
+ static constexpr const TSymbolUniqueId acos_Float2 = TSymbolUniqueId(29);
+ static constexpr const TSymbolUniqueId acos_Float3 = TSymbolUniqueId(30);
+ static constexpr const TSymbolUniqueId acos_Float4 = TSymbolUniqueId(31);
+ static constexpr const TSymbolUniqueId atan_Float1_Float1 = TSymbolUniqueId(32);
+ static constexpr const TSymbolUniqueId atan_Float2_Float2 = TSymbolUniqueId(33);
+ static constexpr const TSymbolUniqueId atan_Float3_Float3 = TSymbolUniqueId(34);
+ static constexpr const TSymbolUniqueId atan_Float4_Float4 = TSymbolUniqueId(35);
+ static constexpr const TSymbolUniqueId atan_Float1 = TSymbolUniqueId(36);
+ static constexpr const TSymbolUniqueId atan_Float2 = TSymbolUniqueId(37);
+ static constexpr const TSymbolUniqueId atan_Float3 = TSymbolUniqueId(38);
+ static constexpr const TSymbolUniqueId atan_Float4 = TSymbolUniqueId(39);
+ static constexpr const TSymbolUniqueId sinh_Float1 = TSymbolUniqueId(40);
+ static constexpr const TSymbolUniqueId sinh_Float2 = TSymbolUniqueId(41);
+ static constexpr const TSymbolUniqueId sinh_Float3 = TSymbolUniqueId(42);
+ static constexpr const TSymbolUniqueId sinh_Float4 = TSymbolUniqueId(43);
+ static constexpr const TSymbolUniqueId cosh_Float1 = TSymbolUniqueId(44);
+ static constexpr const TSymbolUniqueId cosh_Float2 = TSymbolUniqueId(45);
+ static constexpr const TSymbolUniqueId cosh_Float3 = TSymbolUniqueId(46);
+ static constexpr const TSymbolUniqueId cosh_Float4 = TSymbolUniqueId(47);
+ static constexpr const TSymbolUniqueId tanh_Float1 = TSymbolUniqueId(48);
+ static constexpr const TSymbolUniqueId tanh_Float2 = TSymbolUniqueId(49);
+ static constexpr const TSymbolUniqueId tanh_Float3 = TSymbolUniqueId(50);
+ static constexpr const TSymbolUniqueId tanh_Float4 = TSymbolUniqueId(51);
+ static constexpr const TSymbolUniqueId asinh_Float1 = TSymbolUniqueId(52);
+ static constexpr const TSymbolUniqueId asinh_Float2 = TSymbolUniqueId(53);
+ static constexpr const TSymbolUniqueId asinh_Float3 = TSymbolUniqueId(54);
+ static constexpr const TSymbolUniqueId asinh_Float4 = TSymbolUniqueId(55);
+ static constexpr const TSymbolUniqueId acosh_Float1 = TSymbolUniqueId(56);
+ static constexpr const TSymbolUniqueId acosh_Float2 = TSymbolUniqueId(57);
+ static constexpr const TSymbolUniqueId acosh_Float3 = TSymbolUniqueId(58);
+ static constexpr const TSymbolUniqueId acosh_Float4 = TSymbolUniqueId(59);
+ static constexpr const TSymbolUniqueId atanh_Float1 = TSymbolUniqueId(60);
+ static constexpr const TSymbolUniqueId atanh_Float2 = TSymbolUniqueId(61);
+ static constexpr const TSymbolUniqueId atanh_Float3 = TSymbolUniqueId(62);
+ static constexpr const TSymbolUniqueId atanh_Float4 = TSymbolUniqueId(63);
+ static constexpr const TSymbolUniqueId pow_Float1_Float1 = TSymbolUniqueId(64);
+ static constexpr const TSymbolUniqueId pow_Float2_Float2 = TSymbolUniqueId(65);
+ static constexpr const TSymbolUniqueId pow_Float3_Float3 = TSymbolUniqueId(66);
+ static constexpr const TSymbolUniqueId pow_Float4_Float4 = TSymbolUniqueId(67);
+ static constexpr const TSymbolUniqueId exp_Float1 = TSymbolUniqueId(68);
+ static constexpr const TSymbolUniqueId exp_Float2 = TSymbolUniqueId(69);
+ static constexpr const TSymbolUniqueId exp_Float3 = TSymbolUniqueId(70);
+ static constexpr const TSymbolUniqueId exp_Float4 = TSymbolUniqueId(71);
+ static constexpr const TSymbolUniqueId log_Float1 = TSymbolUniqueId(72);
+ static constexpr const TSymbolUniqueId log_Float2 = TSymbolUniqueId(73);
+ static constexpr const TSymbolUniqueId log_Float3 = TSymbolUniqueId(74);
+ static constexpr const TSymbolUniqueId log_Float4 = TSymbolUniqueId(75);
+ static constexpr const TSymbolUniqueId exp2_Float1 = TSymbolUniqueId(76);
+ static constexpr const TSymbolUniqueId exp2_Float2 = TSymbolUniqueId(77);
+ static constexpr const TSymbolUniqueId exp2_Float3 = TSymbolUniqueId(78);
+ static constexpr const TSymbolUniqueId exp2_Float4 = TSymbolUniqueId(79);
+ static constexpr const TSymbolUniqueId log2_Float1 = TSymbolUniqueId(80);
+ static constexpr const TSymbolUniqueId log2_Float2 = TSymbolUniqueId(81);
+ static constexpr const TSymbolUniqueId log2_Float3 = TSymbolUniqueId(82);
+ static constexpr const TSymbolUniqueId log2_Float4 = TSymbolUniqueId(83);
+ static constexpr const TSymbolUniqueId sqrt_Float1 = TSymbolUniqueId(84);
+ static constexpr const TSymbolUniqueId sqrt_Float2 = TSymbolUniqueId(85);
+ static constexpr const TSymbolUniqueId sqrt_Float3 = TSymbolUniqueId(86);
+ static constexpr const TSymbolUniqueId sqrt_Float4 = TSymbolUniqueId(87);
+ static constexpr const TSymbolUniqueId sqrt_Double1 = TSymbolUniqueId(88);
+ static constexpr const TSymbolUniqueId pt00C = TSymbolUniqueId(89);
+ static constexpr const TSymbolUniqueId sqrt_Double2 = TSymbolUniqueId(90);
+ static constexpr const TSymbolUniqueId pt10C = TSymbolUniqueId(91);
+ static constexpr const TSymbolUniqueId sqrt_Double3 = TSymbolUniqueId(92);
+ static constexpr const TSymbolUniqueId pt20C = TSymbolUniqueId(93);
+ static constexpr const TSymbolUniqueId sqrt_Double4 = TSymbolUniqueId(94);
+ static constexpr const TSymbolUniqueId pt30C = TSymbolUniqueId(95);
+ static constexpr const TSymbolUniqueId inversesqrt_Float1 = TSymbolUniqueId(96);
+ static constexpr const TSymbolUniqueId inversesqrt_Float2 = TSymbolUniqueId(97);
+ static constexpr const TSymbolUniqueId inversesqrt_Float3 = TSymbolUniqueId(98);
+ static constexpr const TSymbolUniqueId inversesqrt_Float4 = TSymbolUniqueId(99);
+ static constexpr const TSymbolUniqueId inversesqrt_Double1 = TSymbolUniqueId(100);
+ static constexpr const TSymbolUniqueId inversesqrt_Double2 = TSymbolUniqueId(101);
+ static constexpr const TSymbolUniqueId inversesqrt_Double3 = TSymbolUniqueId(102);
+ static constexpr const TSymbolUniqueId inversesqrt_Double4 = TSymbolUniqueId(103);
+ static constexpr const TSymbolUniqueId abs_Float1 = TSymbolUniqueId(104);
+ static constexpr const TSymbolUniqueId abs_Float2 = TSymbolUniqueId(105);
+ static constexpr const TSymbolUniqueId abs_Float3 = TSymbolUniqueId(106);
+ static constexpr const TSymbolUniqueId abs_Float4 = TSymbolUniqueId(107);
+ static constexpr const TSymbolUniqueId abs_Int1 = TSymbolUniqueId(108);
+ static constexpr const TSymbolUniqueId pt00D = TSymbolUniqueId(109);
+ static constexpr const TSymbolUniqueId abs_Int2 = TSymbolUniqueId(110);
+ static constexpr const TSymbolUniqueId pt10D = TSymbolUniqueId(111);
+ static constexpr const TSymbolUniqueId abs_Int3 = TSymbolUniqueId(112);
+ static constexpr const TSymbolUniqueId pt20D = TSymbolUniqueId(113);
+ static constexpr const TSymbolUniqueId abs_Int4 = TSymbolUniqueId(114);
+ static constexpr const TSymbolUniqueId pt30D = TSymbolUniqueId(115);
+ static constexpr const TSymbolUniqueId abs_Double1 = TSymbolUniqueId(116);
+ static constexpr const TSymbolUniqueId abs_Double2 = TSymbolUniqueId(117);
+ static constexpr const TSymbolUniqueId abs_Double3 = TSymbolUniqueId(118);
+ static constexpr const TSymbolUniqueId abs_Double4 = TSymbolUniqueId(119);
+ static constexpr const TSymbolUniqueId sign_Float1 = TSymbolUniqueId(120);
+ static constexpr const TSymbolUniqueId sign_Float2 = TSymbolUniqueId(121);
+ static constexpr const TSymbolUniqueId sign_Float3 = TSymbolUniqueId(122);
+ static constexpr const TSymbolUniqueId sign_Float4 = TSymbolUniqueId(123);
+ static constexpr const TSymbolUniqueId sign_Int1 = TSymbolUniqueId(124);
+ static constexpr const TSymbolUniqueId sign_Int2 = TSymbolUniqueId(125);
+ static constexpr const TSymbolUniqueId sign_Int3 = TSymbolUniqueId(126);
+ static constexpr const TSymbolUniqueId sign_Int4 = TSymbolUniqueId(127);
+ static constexpr const TSymbolUniqueId sign_Double1 = TSymbolUniqueId(128);
+ static constexpr const TSymbolUniqueId sign_Double2 = TSymbolUniqueId(129);
+ static constexpr const TSymbolUniqueId sign_Double3 = TSymbolUniqueId(130);
+ static constexpr const TSymbolUniqueId sign_Double4 = TSymbolUniqueId(131);
+ static constexpr const TSymbolUniqueId floor_Float1 = TSymbolUniqueId(132);
+ static constexpr const TSymbolUniqueId floor_Float2 = TSymbolUniqueId(133);
+ static constexpr const TSymbolUniqueId floor_Float3 = TSymbolUniqueId(134);
+ static constexpr const TSymbolUniqueId floor_Float4 = TSymbolUniqueId(135);
+ static constexpr const TSymbolUniqueId floor_Double1 = TSymbolUniqueId(136);
+ static constexpr const TSymbolUniqueId floor_Double2 = TSymbolUniqueId(137);
+ static constexpr const TSymbolUniqueId floor_Double3 = TSymbolUniqueId(138);
+ static constexpr const TSymbolUniqueId floor_Double4 = TSymbolUniqueId(139);
+ static constexpr const TSymbolUniqueId trunc_Float1 = TSymbolUniqueId(140);
+ static constexpr const TSymbolUniqueId trunc_Float2 = TSymbolUniqueId(141);
+ static constexpr const TSymbolUniqueId trunc_Float3 = TSymbolUniqueId(142);
+ static constexpr const TSymbolUniqueId trunc_Float4 = TSymbolUniqueId(143);
+ static constexpr const TSymbolUniqueId trunc_Double1 = TSymbolUniqueId(144);
+ static constexpr const TSymbolUniqueId trunc_Double2 = TSymbolUniqueId(145);
+ static constexpr const TSymbolUniqueId trunc_Double3 = TSymbolUniqueId(146);
+ static constexpr const TSymbolUniqueId trunc_Double4 = TSymbolUniqueId(147);
+ static constexpr const TSymbolUniqueId round_Float1 = TSymbolUniqueId(148);
+ static constexpr const TSymbolUniqueId round_Float2 = TSymbolUniqueId(149);
+ static constexpr const TSymbolUniqueId round_Float3 = TSymbolUniqueId(150);
+ static constexpr const TSymbolUniqueId round_Float4 = TSymbolUniqueId(151);
+ static constexpr const TSymbolUniqueId round_Double1 = TSymbolUniqueId(152);
+ static constexpr const TSymbolUniqueId round_Double2 = TSymbolUniqueId(153);
+ static constexpr const TSymbolUniqueId round_Double3 = TSymbolUniqueId(154);
+ static constexpr const TSymbolUniqueId round_Double4 = TSymbolUniqueId(155);
+ static constexpr const TSymbolUniqueId roundEven_Float1 = TSymbolUniqueId(156);
+ static constexpr const TSymbolUniqueId roundEven_Float2 = TSymbolUniqueId(157);
+ static constexpr const TSymbolUniqueId roundEven_Float3 = TSymbolUniqueId(158);
+ static constexpr const TSymbolUniqueId roundEven_Float4 = TSymbolUniqueId(159);
+ static constexpr const TSymbolUniqueId roundEven_Double1 = TSymbolUniqueId(160);
+ static constexpr const TSymbolUniqueId roundEven_Double2 = TSymbolUniqueId(161);
+ static constexpr const TSymbolUniqueId roundEven_Double3 = TSymbolUniqueId(162);
+ static constexpr const TSymbolUniqueId roundEven_Double4 = TSymbolUniqueId(163);
+ static constexpr const TSymbolUniqueId ceil_Float1 = TSymbolUniqueId(164);
+ static constexpr const TSymbolUniqueId ceil_Float2 = TSymbolUniqueId(165);
+ static constexpr const TSymbolUniqueId ceil_Float3 = TSymbolUniqueId(166);
+ static constexpr const TSymbolUniqueId ceil_Float4 = TSymbolUniqueId(167);
+ static constexpr const TSymbolUniqueId ceil_Double1 = TSymbolUniqueId(168);
+ static constexpr const TSymbolUniqueId ceil_Double2 = TSymbolUniqueId(169);
+ static constexpr const TSymbolUniqueId ceil_Double3 = TSymbolUniqueId(170);
+ static constexpr const TSymbolUniqueId ceil_Double4 = TSymbolUniqueId(171);
+ static constexpr const TSymbolUniqueId fract_Float1 = TSymbolUniqueId(172);
+ static constexpr const TSymbolUniqueId fract_Float2 = TSymbolUniqueId(173);
+ static constexpr const TSymbolUniqueId fract_Float3 = TSymbolUniqueId(174);
+ static constexpr const TSymbolUniqueId fract_Float4 = TSymbolUniqueId(175);
+ static constexpr const TSymbolUniqueId fract_Double1 = TSymbolUniqueId(176);
+ static constexpr const TSymbolUniqueId fract_Double2 = TSymbolUniqueId(177);
+ static constexpr const TSymbolUniqueId fract_Double3 = TSymbolUniqueId(178);
+ static constexpr const TSymbolUniqueId fract_Double4 = TSymbolUniqueId(179);
+ static constexpr const TSymbolUniqueId mod_Float1_Float1 = TSymbolUniqueId(180);
+ static constexpr const TSymbolUniqueId mod_Float2_Float1 = TSymbolUniqueId(181);
+ static constexpr const TSymbolUniqueId mod_Float3_Float1 = TSymbolUniqueId(182);
+ static constexpr const TSymbolUniqueId mod_Float4_Float1 = TSymbolUniqueId(183);
+ static constexpr const TSymbolUniqueId mod_Float2_Float2 = TSymbolUniqueId(184);
+ static constexpr const TSymbolUniqueId mod_Float3_Float3 = TSymbolUniqueId(185);
+ static constexpr const TSymbolUniqueId mod_Float4_Float4 = TSymbolUniqueId(186);
+ static constexpr const TSymbolUniqueId mod_Double1_Double1 = TSymbolUniqueId(187);
+ static constexpr const TSymbolUniqueId mod_Double2_Double1 = TSymbolUniqueId(188);
+ static constexpr const TSymbolUniqueId mod_Double3_Double1 = TSymbolUniqueId(189);
+ static constexpr const TSymbolUniqueId mod_Double4_Double1 = TSymbolUniqueId(190);
+ static constexpr const TSymbolUniqueId mod_Double2_Double2 = TSymbolUniqueId(191);
+ static constexpr const TSymbolUniqueId mod_Double3_Double3 = TSymbolUniqueId(192);
+ static constexpr const TSymbolUniqueId mod_Double4_Double4 = TSymbolUniqueId(193);
+ static constexpr const TSymbolUniqueId min_Float1_Float1 = TSymbolUniqueId(194);
+ static constexpr const TSymbolUniqueId min_Float2_Float1 = TSymbolUniqueId(195);
+ static constexpr const TSymbolUniqueId min_Float3_Float1 = TSymbolUniqueId(196);
+ static constexpr const TSymbolUniqueId min_Float4_Float1 = TSymbolUniqueId(197);
+ static constexpr const TSymbolUniqueId min_Float2_Float2 = TSymbolUniqueId(198);
+ static constexpr const TSymbolUniqueId min_Float3_Float3 = TSymbolUniqueId(199);
+ static constexpr const TSymbolUniqueId min_Float4_Float4 = TSymbolUniqueId(200);
+ static constexpr const TSymbolUniqueId min_Double1_Double1 = TSymbolUniqueId(201);
+ static constexpr const TSymbolUniqueId min_Double2_Double2 = TSymbolUniqueId(202);
+ static constexpr const TSymbolUniqueId min_Double3_Double3 = TSymbolUniqueId(203);
+ static constexpr const TSymbolUniqueId min_Double4_Double4 = TSymbolUniqueId(204);
+ static constexpr const TSymbolUniqueId min_Double2_Double1 = TSymbolUniqueId(205);
+ static constexpr const TSymbolUniqueId min_Double3_Double1 = TSymbolUniqueId(206);
+ static constexpr const TSymbolUniqueId min_Double4_Double1 = TSymbolUniqueId(207);
+ static constexpr const TSymbolUniqueId min_Int1_Int1 = TSymbolUniqueId(208);
+ static constexpr const TSymbolUniqueId min_Int2_Int2 = TSymbolUniqueId(209);
+ static constexpr const TSymbolUniqueId min_Int3_Int3 = TSymbolUniqueId(210);
+ static constexpr const TSymbolUniqueId min_Int4_Int4 = TSymbolUniqueId(211);
+ static constexpr const TSymbolUniqueId min_Int2_Int1 = TSymbolUniqueId(212);
+ static constexpr const TSymbolUniqueId min_Int3_Int1 = TSymbolUniqueId(213);
+ static constexpr const TSymbolUniqueId min_Int4_Int1 = TSymbolUniqueId(214);
+ static constexpr const TSymbolUniqueId min_UInt1_UInt1 = TSymbolUniqueId(215);
+ static constexpr const TSymbolUniqueId pt00E = TSymbolUniqueId(216);
+ static constexpr const TSymbolUniqueId min_UInt2_UInt2 = TSymbolUniqueId(217);
+ static constexpr const TSymbolUniqueId pt10E = TSymbolUniqueId(218);
+ static constexpr const TSymbolUniqueId min_UInt3_UInt3 = TSymbolUniqueId(219);
+ static constexpr const TSymbolUniqueId pt20E = TSymbolUniqueId(220);
+ static constexpr const TSymbolUniqueId min_UInt4_UInt4 = TSymbolUniqueId(221);
+ static constexpr const TSymbolUniqueId pt30E = TSymbolUniqueId(222);
+ static constexpr const TSymbolUniqueId min_UInt2_UInt1 = TSymbolUniqueId(223);
+ static constexpr const TSymbolUniqueId min_UInt3_UInt1 = TSymbolUniqueId(224);
+ static constexpr const TSymbolUniqueId min_UInt4_UInt1 = TSymbolUniqueId(225);
+ static constexpr const TSymbolUniqueId max_Float1_Float1 = TSymbolUniqueId(226);
+ static constexpr const TSymbolUniqueId max_Float2_Float1 = TSymbolUniqueId(227);
+ static constexpr const TSymbolUniqueId max_Float3_Float1 = TSymbolUniqueId(228);
+ static constexpr const TSymbolUniqueId max_Float4_Float1 = TSymbolUniqueId(229);
+ static constexpr const TSymbolUniqueId max_Float2_Float2 = TSymbolUniqueId(230);
+ static constexpr const TSymbolUniqueId max_Float3_Float3 = TSymbolUniqueId(231);
+ static constexpr const TSymbolUniqueId max_Float4_Float4 = TSymbolUniqueId(232);
+ static constexpr const TSymbolUniqueId max_Double1_Double1 = TSymbolUniqueId(233);
+ static constexpr const TSymbolUniqueId max_Double2_Double2 = TSymbolUniqueId(234);
+ static constexpr const TSymbolUniqueId max_Double3_Double3 = TSymbolUniqueId(235);
+ static constexpr const TSymbolUniqueId max_Double4_Double4 = TSymbolUniqueId(236);
+ static constexpr const TSymbolUniqueId max_Double2_Double1 = TSymbolUniqueId(237);
+ static constexpr const TSymbolUniqueId max_Double3_Double1 = TSymbolUniqueId(238);
+ static constexpr const TSymbolUniqueId max_Double4_Double1 = TSymbolUniqueId(239);
+ static constexpr const TSymbolUniqueId max_Int1_Int1 = TSymbolUniqueId(240);
+ static constexpr const TSymbolUniqueId max_Int2_Int2 = TSymbolUniqueId(241);
+ static constexpr const TSymbolUniqueId max_Int3_Int3 = TSymbolUniqueId(242);
+ static constexpr const TSymbolUniqueId max_Int4_Int4 = TSymbolUniqueId(243);
+ static constexpr const TSymbolUniqueId max_Int2_Int1 = TSymbolUniqueId(244);
+ static constexpr const TSymbolUniqueId max_Int3_Int1 = TSymbolUniqueId(245);
+ static constexpr const TSymbolUniqueId max_Int4_Int1 = TSymbolUniqueId(246);
+ static constexpr const TSymbolUniqueId max_UInt1_UInt1 = TSymbolUniqueId(247);
+ static constexpr const TSymbolUniqueId max_UInt2_UInt2 = TSymbolUniqueId(248);
+ static constexpr const TSymbolUniqueId max_UInt3_UInt3 = TSymbolUniqueId(249);
+ static constexpr const TSymbolUniqueId max_UInt4_UInt4 = TSymbolUniqueId(250);
+ static constexpr const TSymbolUniqueId max_UInt2_UInt1 = TSymbolUniqueId(251);
+ static constexpr const TSymbolUniqueId max_UInt3_UInt1 = TSymbolUniqueId(252);
+ static constexpr const TSymbolUniqueId max_UInt4_UInt1 = TSymbolUniqueId(253);
+ static constexpr const TSymbolUniqueId clamp_Float1_Float1_Float1 = TSymbolUniqueId(254);
+ static constexpr const TSymbolUniqueId clamp_Float2_Float1_Float1 = TSymbolUniqueId(255);
+ static constexpr const TSymbolUniqueId clamp_Float3_Float1_Float1 = TSymbolUniqueId(256);
+ static constexpr const TSymbolUniqueId clamp_Float4_Float1_Float1 = TSymbolUniqueId(257);
+ static constexpr const TSymbolUniqueId clamp_Float2_Float2_Float2 = TSymbolUniqueId(258);
+ static constexpr const TSymbolUniqueId clamp_Float3_Float3_Float3 = TSymbolUniqueId(259);
+ static constexpr const TSymbolUniqueId clamp_Float4_Float4_Float4 = TSymbolUniqueId(260);
+ static constexpr const TSymbolUniqueId clamp_Double1_Double1_Double1 = TSymbolUniqueId(261);
+ static constexpr const TSymbolUniqueId clamp_Double2_Double1_Double1 = TSymbolUniqueId(262);
+ static constexpr const TSymbolUniqueId clamp_Double3_Double1_Double1 = TSymbolUniqueId(263);
+ static constexpr const TSymbolUniqueId clamp_Double4_Double1_Double1 = TSymbolUniqueId(264);
+ static constexpr const TSymbolUniqueId clamp_Double2_Double2_Double2 = TSymbolUniqueId(265);
+ static constexpr const TSymbolUniqueId clamp_Double3_Double3_Double3 = TSymbolUniqueId(266);
+ static constexpr const TSymbolUniqueId clamp_Double4_Double4_Double4 = TSymbolUniqueId(267);
+ static constexpr const TSymbolUniqueId clamp_Int1_Int1_Int1 = TSymbolUniqueId(268);
+ static constexpr const TSymbolUniqueId clamp_Int2_Int1_Int1 = TSymbolUniqueId(269);
+ static constexpr const TSymbolUniqueId clamp_Int3_Int1_Int1 = TSymbolUniqueId(270);
+ static constexpr const TSymbolUniqueId clamp_Int4_Int1_Int1 = TSymbolUniqueId(271);
+ static constexpr const TSymbolUniqueId clamp_Int2_Int2_Int2 = TSymbolUniqueId(272);
+ static constexpr const TSymbolUniqueId clamp_Int3_Int3_Int3 = TSymbolUniqueId(273);
+ static constexpr const TSymbolUniqueId clamp_Int4_Int4_Int4 = TSymbolUniqueId(274);
+ static constexpr const TSymbolUniqueId clamp_UInt1_UInt1_UInt1 = TSymbolUniqueId(275);
+ static constexpr const TSymbolUniqueId clamp_UInt2_UInt1_UInt1 = TSymbolUniqueId(276);
+ static constexpr const TSymbolUniqueId clamp_UInt3_UInt1_UInt1 = TSymbolUniqueId(277);
+ static constexpr const TSymbolUniqueId clamp_UInt4_UInt1_UInt1 = TSymbolUniqueId(278);
+ static constexpr const TSymbolUniqueId clamp_UInt2_UInt2_UInt2 = TSymbolUniqueId(279);
+ static constexpr const TSymbolUniqueId clamp_UInt3_UInt3_UInt3 = TSymbolUniqueId(280);
+ static constexpr const TSymbolUniqueId clamp_UInt4_UInt4_UInt4 = TSymbolUniqueId(281);
+ static constexpr const TSymbolUniqueId mix_Float1_Float1_Float1 = TSymbolUniqueId(282);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Float1 = TSymbolUniqueId(283);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Float1 = TSymbolUniqueId(284);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Float1 = TSymbolUniqueId(285);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Float2 = TSymbolUniqueId(286);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Float3 = TSymbolUniqueId(287);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Float4 = TSymbolUniqueId(288);
+ static constexpr const TSymbolUniqueId mix_Double1_Double1_Double1 = TSymbolUniqueId(289);
+ static constexpr const TSymbolUniqueId mix_Double2_Double2_Double1 = TSymbolUniqueId(290);
+ static constexpr const TSymbolUniqueId mix_Double3_Double3_Double1 = TSymbolUniqueId(291);
+ static constexpr const TSymbolUniqueId mix_Double4_Double4_Double1 = TSymbolUniqueId(292);
+ static constexpr const TSymbolUniqueId mix_Double2_Double2_Double2 = TSymbolUniqueId(293);
+ static constexpr const TSymbolUniqueId mix_Double3_Double3_Double3 = TSymbolUniqueId(294);
+ static constexpr const TSymbolUniqueId mix_Double4_Double4_Double4 = TSymbolUniqueId(295);
+ static constexpr const TSymbolUniqueId mix_Float1_Float1_Bool1 = TSymbolUniqueId(296);
+ static constexpr const TSymbolUniqueId pt00F = TSymbolUniqueId(297);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Bool2 = TSymbolUniqueId(298);
+ static constexpr const TSymbolUniqueId pt10F = TSymbolUniqueId(299);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Bool3 = TSymbolUniqueId(300);
+ static constexpr const TSymbolUniqueId pt20F = TSymbolUniqueId(301);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Bool4 = TSymbolUniqueId(302);
+ static constexpr const TSymbolUniqueId pt30F = TSymbolUniqueId(303);
+ static constexpr const TSymbolUniqueId mix_Double1_Double1_Bool1 = TSymbolUniqueId(304);
+ static constexpr const TSymbolUniqueId mix_Double2_Double2_Bool2 = TSymbolUniqueId(305);
+ static constexpr const TSymbolUniqueId mix_Double3_Double3_Bool3 = TSymbolUniqueId(306);
+ static constexpr const TSymbolUniqueId mix_Double4_Double4_Bool4 = TSymbolUniqueId(307);
+ static constexpr const TSymbolUniqueId mix_Int1_Int1_Bool1 = TSymbolUniqueId(308);
+ static constexpr const TSymbolUniqueId mix_Int2_Int2_Bool2 = TSymbolUniqueId(309);
+ static constexpr const TSymbolUniqueId mix_Int3_Int3_Bool3 = TSymbolUniqueId(310);
+ static constexpr const TSymbolUniqueId mix_Int4_Int4_Bool4 = TSymbolUniqueId(311);
+ static constexpr const TSymbolUniqueId mix_UInt1_UInt1_Bool1 = TSymbolUniqueId(312);
+ static constexpr const TSymbolUniqueId mix_UInt2_UInt2_Bool2 = TSymbolUniqueId(313);
+ static constexpr const TSymbolUniqueId mix_UInt3_UInt3_Bool3 = TSymbolUniqueId(314);
+ static constexpr const TSymbolUniqueId mix_UInt4_UInt4_Bool4 = TSymbolUniqueId(315);
+ static constexpr const TSymbolUniqueId mix_Bool1_Bool1_Bool1 = TSymbolUniqueId(316);
+ static constexpr const TSymbolUniqueId mix_Bool2_Bool2_Bool2 = TSymbolUniqueId(317);
+ static constexpr const TSymbolUniqueId mix_Bool3_Bool3_Bool3 = TSymbolUniqueId(318);
+ static constexpr const TSymbolUniqueId mix_Bool4_Bool4_Bool4 = TSymbolUniqueId(319);
+ static constexpr const TSymbolUniqueId step_Float1_Float1 = TSymbolUniqueId(320);
+ static constexpr const TSymbolUniqueId step_Float2_Float2 = TSymbolUniqueId(321);
+ static constexpr const TSymbolUniqueId step_Float3_Float3 = TSymbolUniqueId(322);
+ static constexpr const TSymbolUniqueId step_Float4_Float4 = TSymbolUniqueId(323);
+ static constexpr const TSymbolUniqueId step_Float1_Float2 = TSymbolUniqueId(324);
+ static constexpr const TSymbolUniqueId step_Float1_Float3 = TSymbolUniqueId(325);
+ static constexpr const TSymbolUniqueId step_Float1_Float4 = TSymbolUniqueId(326);
+ static constexpr const TSymbolUniqueId step_Double1_Double1 = TSymbolUniqueId(327);
+ static constexpr const TSymbolUniqueId step_Double2_Double2 = TSymbolUniqueId(328);
+ static constexpr const TSymbolUniqueId step_Double3_Double3 = TSymbolUniqueId(329);
+ static constexpr const TSymbolUniqueId step_Double4_Double4 = TSymbolUniqueId(330);
+ static constexpr const TSymbolUniqueId step_Double1_Double2 = TSymbolUniqueId(331);
+ static constexpr const TSymbolUniqueId step_Double1_Double3 = TSymbolUniqueId(332);
+ static constexpr const TSymbolUniqueId step_Double1_Double4 = TSymbolUniqueId(333);
+ static constexpr const TSymbolUniqueId smoothstep_Double1_Double1_Double1 =
+ TSymbolUniqueId(334);
+ static constexpr const TSymbolUniqueId smoothstep_Double2_Double2_Double2 =
+ TSymbolUniqueId(335);
+ static constexpr const TSymbolUniqueId smoothstep_Double3_Double3_Double3 =
+ TSymbolUniqueId(336);
+ static constexpr const TSymbolUniqueId smoothstep_Double4_Double4_Double4 =
+ TSymbolUniqueId(337);
+ static constexpr const TSymbolUniqueId smoothstep_Double1_Double1_Double2 =
+ TSymbolUniqueId(338);
+ static constexpr const TSymbolUniqueId smoothstep_Double1_Double1_Double3 =
+ TSymbolUniqueId(339);
+ static constexpr const TSymbolUniqueId smoothstep_Double1_Double1_Double4 =
+ TSymbolUniqueId(340);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float1 = TSymbolUniqueId(341);
+ static constexpr const TSymbolUniqueId smoothstep_Float2_Float2_Float2 = TSymbolUniqueId(342);
+ static constexpr const TSymbolUniqueId smoothstep_Float3_Float3_Float3 = TSymbolUniqueId(343);
+ static constexpr const TSymbolUniqueId smoothstep_Float4_Float4_Float4 = TSymbolUniqueId(344);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float2 = TSymbolUniqueId(345);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float3 = TSymbolUniqueId(346);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float4 = TSymbolUniqueId(347);
+ static constexpr const TSymbolUniqueId modf_Float1_Float1 = TSymbolUniqueId(348);
+ static constexpr const TSymbolUniqueId pt_o_00B = TSymbolUniqueId(349);
+ static constexpr const TSymbolUniqueId modf_Float2_Float2 = TSymbolUniqueId(350);
+ static constexpr const TSymbolUniqueId pt_o_10B = TSymbolUniqueId(351);
+ static constexpr const TSymbolUniqueId modf_Float3_Float3 = TSymbolUniqueId(352);
+ static constexpr const TSymbolUniqueId pt_o_20B = TSymbolUniqueId(353);
+ static constexpr const TSymbolUniqueId modf_Float4_Float4 = TSymbolUniqueId(354);
+ static constexpr const TSymbolUniqueId pt_o_30B = TSymbolUniqueId(355);
+ static constexpr const TSymbolUniqueId modf_Double1_Double1 = TSymbolUniqueId(356);
+ static constexpr const TSymbolUniqueId pt_o_00C = TSymbolUniqueId(357);
+ static constexpr const TSymbolUniqueId modf_Double2_Double2 = TSymbolUniqueId(358);
+ static constexpr const TSymbolUniqueId pt_o_10C = TSymbolUniqueId(359);
+ static constexpr const TSymbolUniqueId modf_Double3_Double3 = TSymbolUniqueId(360);
+ static constexpr const TSymbolUniqueId pt_o_20C = TSymbolUniqueId(361);
+ static constexpr const TSymbolUniqueId modf_Double4_Double4 = TSymbolUniqueId(362);
+ static constexpr const TSymbolUniqueId pt_o_30C = TSymbolUniqueId(363);
+ static constexpr const TSymbolUniqueId isnan_Float1 = TSymbolUniqueId(364);
+ static constexpr const TSymbolUniqueId isnan_Float2 = TSymbolUniqueId(365);
+ static constexpr const TSymbolUniqueId isnan_Float3 = TSymbolUniqueId(366);
+ static constexpr const TSymbolUniqueId isnan_Float4 = TSymbolUniqueId(367);
+ static constexpr const TSymbolUniqueId isnan_Double1 = TSymbolUniqueId(368);
+ static constexpr const TSymbolUniqueId isnan_Double2 = TSymbolUniqueId(369);
+ static constexpr const TSymbolUniqueId isnan_Double3 = TSymbolUniqueId(370);
+ static constexpr const TSymbolUniqueId isnan_Double4 = TSymbolUniqueId(371);
+ static constexpr const TSymbolUniqueId isinf_Float1 = TSymbolUniqueId(372);
+ static constexpr const TSymbolUniqueId isinf_Float2 = TSymbolUniqueId(373);
+ static constexpr const TSymbolUniqueId isinf_Float3 = TSymbolUniqueId(374);
+ static constexpr const TSymbolUniqueId isinf_Float4 = TSymbolUniqueId(375);
+ static constexpr const TSymbolUniqueId isinf_Double1 = TSymbolUniqueId(376);
+ static constexpr const TSymbolUniqueId isinf_Double2 = TSymbolUniqueId(377);
+ static constexpr const TSymbolUniqueId isinf_Double3 = TSymbolUniqueId(378);
+ static constexpr const TSymbolUniqueId isinf_Double4 = TSymbolUniqueId(379);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float1 = TSymbolUniqueId(380);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float2 = TSymbolUniqueId(381);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float3 = TSymbolUniqueId(382);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float4 = TSymbolUniqueId(383);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float1 = TSymbolUniqueId(384);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float2 = TSymbolUniqueId(385);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float3 = TSymbolUniqueId(386);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float4 = TSymbolUniqueId(387);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int1 = TSymbolUniqueId(388);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int2 = TSymbolUniqueId(389);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int3 = TSymbolUniqueId(390);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int4 = TSymbolUniqueId(391);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt1 = TSymbolUniqueId(392);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt2 = TSymbolUniqueId(393);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt3 = TSymbolUniqueId(394);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt4 = TSymbolUniqueId(395);
+ static constexpr const TSymbolUniqueId fma_Float1_Float1_Float1 = TSymbolUniqueId(396);
+ static constexpr const TSymbolUniqueId fma_Float2_Float2_Float2 = TSymbolUniqueId(397);
+ static constexpr const TSymbolUniqueId fma_Float3_Float3_Float3 = TSymbolUniqueId(398);
+ static constexpr const TSymbolUniqueId fma_Float4_Float4_Float4 = TSymbolUniqueId(399);
+ static constexpr const TSymbolUniqueId fmaExt_Float1_Float1_Float1 = TSymbolUniqueId(400);
+ static constexpr const TSymbolUniqueId fmaExt_Float2_Float2_Float2 = TSymbolUniqueId(401);
+ static constexpr const TSymbolUniqueId fmaExt_Float3_Float3_Float3 = TSymbolUniqueId(402);
+ static constexpr const TSymbolUniqueId fmaExt_Float4_Float4_Float4 = TSymbolUniqueId(403);
+ static constexpr const TSymbolUniqueId fma_Double1_Double1_Double1 = TSymbolUniqueId(404);
+ static constexpr const TSymbolUniqueId fma_Double2_Double2_Double2 = TSymbolUniqueId(405);
+ static constexpr const TSymbolUniqueId fma_Double3_Double3_Double3 = TSymbolUniqueId(406);
+ static constexpr const TSymbolUniqueId fma_Double4_Double4_Double4 = TSymbolUniqueId(407);
+ static constexpr const TSymbolUniqueId frexp_Float1_Int1 = TSymbolUniqueId(408);
+ static constexpr const TSymbolUniqueId pt_o_00D = TSymbolUniqueId(409);
+ static constexpr const TSymbolUniqueId frexp_Float2_Int2 = TSymbolUniqueId(410);
+ static constexpr const TSymbolUniqueId pt_o_10D = TSymbolUniqueId(411);
+ static constexpr const TSymbolUniqueId frexp_Float3_Int3 = TSymbolUniqueId(412);
+ static constexpr const TSymbolUniqueId pt_o_20D = TSymbolUniqueId(413);
+ static constexpr const TSymbolUniqueId frexp_Float4_Int4 = TSymbolUniqueId(414);
+ static constexpr const TSymbolUniqueId pt_o_30D = TSymbolUniqueId(415);
+ static constexpr const TSymbolUniqueId frexp_Double1_Int1 = TSymbolUniqueId(416);
+ static constexpr const TSymbolUniqueId frexp_Double2_Int2 = TSymbolUniqueId(417);
+ static constexpr const TSymbolUniqueId frexp_Double3_Int3 = TSymbolUniqueId(418);
+ static constexpr const TSymbolUniqueId frexp_Double4_Int4 = TSymbolUniqueId(419);
+ static constexpr const TSymbolUniqueId ldexp_Float1_Int1 = TSymbolUniqueId(420);
+ static constexpr const TSymbolUniqueId ldexp_Float2_Int2 = TSymbolUniqueId(421);
+ static constexpr const TSymbolUniqueId ldexp_Float3_Int3 = TSymbolUniqueId(422);
+ static constexpr const TSymbolUniqueId ldexp_Float4_Int4 = TSymbolUniqueId(423);
+ static constexpr const TSymbolUniqueId ldexp_Double1_Int1 = TSymbolUniqueId(424);
+ static constexpr const TSymbolUniqueId ldexp_Double2_Int2 = TSymbolUniqueId(425);
+ static constexpr const TSymbolUniqueId ldexp_Double3_Int3 = TSymbolUniqueId(426);
+ static constexpr const TSymbolUniqueId ldexp_Double4_Int4 = TSymbolUniqueId(427);
+ static constexpr const TSymbolUniqueId packSnorm2x16_Float2 = TSymbolUniqueId(428);
+ static constexpr const TSymbolUniqueId packHalf2x16_Float2 = TSymbolUniqueId(429);
+ static constexpr const TSymbolUniqueId unpackSnorm2x16_UInt1 = TSymbolUniqueId(430);
+ static constexpr const TSymbolUniqueId unpackHalf2x16_UInt1 = TSymbolUniqueId(431);
+ static constexpr const TSymbolUniqueId packUnorm2x16_Float2 = TSymbolUniqueId(432);
+ static constexpr const TSymbolUniqueId unpackUnorm2x16_UInt1 = TSymbolUniqueId(433);
+ static constexpr const TSymbolUniqueId packUnorm4x8_Float4 = TSymbolUniqueId(434);
+ static constexpr const TSymbolUniqueId packSnorm4x8_Float4 = TSymbolUniqueId(435);
+ static constexpr const TSymbolUniqueId unpackUnorm4x8_UInt1 = TSymbolUniqueId(436);
+ static constexpr const TSymbolUniqueId unpackSnorm4x8_UInt1 = TSymbolUniqueId(437);
+ static constexpr const TSymbolUniqueId packDouble2x32_UInt2 = TSymbolUniqueId(438);
+ static constexpr const TSymbolUniqueId unpackDouble2x32_Double1 = TSymbolUniqueId(439);
+ static constexpr const TSymbolUniqueId length_Float1 = TSymbolUniqueId(440);
+ static constexpr const TSymbolUniqueId length_Float2 = TSymbolUniqueId(441);
+ static constexpr const TSymbolUniqueId length_Float3 = TSymbolUniqueId(442);
+ static constexpr const TSymbolUniqueId length_Float4 = TSymbolUniqueId(443);
+ static constexpr const TSymbolUniqueId length_Double1 = TSymbolUniqueId(444);
+ static constexpr const TSymbolUniqueId length_Double2 = TSymbolUniqueId(445);
+ static constexpr const TSymbolUniqueId length_Double3 = TSymbolUniqueId(446);
+ static constexpr const TSymbolUniqueId length_Double4 = TSymbolUniqueId(447);
+ static constexpr const TSymbolUniqueId distance_Float1_Float1 = TSymbolUniqueId(448);
+ static constexpr const TSymbolUniqueId distance_Float2_Float2 = TSymbolUniqueId(449);
+ static constexpr const TSymbolUniqueId distance_Float3_Float3 = TSymbolUniqueId(450);
+ static constexpr const TSymbolUniqueId distance_Float4_Float4 = TSymbolUniqueId(451);
+ static constexpr const TSymbolUniqueId distance_Double1_Double1 = TSymbolUniqueId(452);
+ static constexpr const TSymbolUniqueId distance_Double2_Double2 = TSymbolUniqueId(453);
+ static constexpr const TSymbolUniqueId distance_Double3_Double3 = TSymbolUniqueId(454);
+ static constexpr const TSymbolUniqueId distance_Double4_Double4 = TSymbolUniqueId(455);
+ static constexpr const TSymbolUniqueId dot_Float1_Float1 = TSymbolUniqueId(456);
+ static constexpr const TSymbolUniqueId dot_Float2_Float2 = TSymbolUniqueId(457);
+ static constexpr const TSymbolUniqueId dot_Float3_Float3 = TSymbolUniqueId(458);
+ static constexpr const TSymbolUniqueId dot_Float4_Float4 = TSymbolUniqueId(459);
+ static constexpr const TSymbolUniqueId dot_Double1_Double1 = TSymbolUniqueId(460);
+ static constexpr const TSymbolUniqueId dot_Double2_Double2 = TSymbolUniqueId(461);
+ static constexpr const TSymbolUniqueId dot_Double3_Double3 = TSymbolUniqueId(462);
+ static constexpr const TSymbolUniqueId dot_Double4_Double4 = TSymbolUniqueId(463);
+ static constexpr const TSymbolUniqueId cross_Float3_Float3 = TSymbolUniqueId(464);
+ static constexpr const TSymbolUniqueId cross_Double3_Double3 = TSymbolUniqueId(465);
+ static constexpr const TSymbolUniqueId normalize_Float1 = TSymbolUniqueId(466);
+ static constexpr const TSymbolUniqueId normalize_Float2 = TSymbolUniqueId(467);
+ static constexpr const TSymbolUniqueId normalize_Float3 = TSymbolUniqueId(468);
+ static constexpr const TSymbolUniqueId normalize_Float4 = TSymbolUniqueId(469);
+ static constexpr const TSymbolUniqueId normalize_Double1 = TSymbolUniqueId(470);
+ static constexpr const TSymbolUniqueId normalize_Double2 = TSymbolUniqueId(471);
+ static constexpr const TSymbolUniqueId normalize_Double3 = TSymbolUniqueId(472);
+ static constexpr const TSymbolUniqueId normalize_Double4 = TSymbolUniqueId(473);
+ static constexpr const TSymbolUniqueId faceforward_Float1_Float1_Float1 = TSymbolUniqueId(474);
+ static constexpr const TSymbolUniqueId faceforward_Float2_Float2_Float2 = TSymbolUniqueId(475);
+ static constexpr const TSymbolUniqueId faceforward_Float3_Float3_Float3 = TSymbolUniqueId(476);
+ static constexpr const TSymbolUniqueId faceforward_Float4_Float4_Float4 = TSymbolUniqueId(477);
+ static constexpr const TSymbolUniqueId faceforward_Double1_Double1_Double1 =
+ TSymbolUniqueId(478);
+ static constexpr const TSymbolUniqueId faceforward_Double2_Double2_Double2 =
+ TSymbolUniqueId(479);
+ static constexpr const TSymbolUniqueId faceforward_Double3_Double3_Double3 =
+ TSymbolUniqueId(480);
+ static constexpr const TSymbolUniqueId faceforward_Double4_Double4_Double4 =
+ TSymbolUniqueId(481);
+ static constexpr const TSymbolUniqueId reflect_Float1_Float1 = TSymbolUniqueId(482);
+ static constexpr const TSymbolUniqueId reflect_Float2_Float2 = TSymbolUniqueId(483);
+ static constexpr const TSymbolUniqueId reflect_Float3_Float3 = TSymbolUniqueId(484);
+ static constexpr const TSymbolUniqueId reflect_Float4_Float4 = TSymbolUniqueId(485);
+ static constexpr const TSymbolUniqueId reflect_Double1_Double1 = TSymbolUniqueId(486);
+ static constexpr const TSymbolUniqueId reflect_Double2_Double2 = TSymbolUniqueId(487);
+ static constexpr const TSymbolUniqueId reflect_Double3_Double3 = TSymbolUniqueId(488);
+ static constexpr const TSymbolUniqueId reflect_Double4_Double4 = TSymbolUniqueId(489);
+ static constexpr const TSymbolUniqueId refract_Float1_Float1_Float1 = TSymbolUniqueId(490);
+ static constexpr const TSymbolUniqueId refract_Float2_Float2_Float1 = TSymbolUniqueId(491);
+ static constexpr const TSymbolUniqueId refract_Float3_Float3_Float1 = TSymbolUniqueId(492);
+ static constexpr const TSymbolUniqueId refract_Float4_Float4_Float1 = TSymbolUniqueId(493);
+ static constexpr const TSymbolUniqueId refract_Double1_Double1_Float1 = TSymbolUniqueId(494);
+ static constexpr const TSymbolUniqueId refract_Double2_Double2_Float1 = TSymbolUniqueId(495);
+ static constexpr const TSymbolUniqueId refract_Double3_Double3_Float1 = TSymbolUniqueId(496);
+ static constexpr const TSymbolUniqueId refract_Double4_Double4_Float1 = TSymbolUniqueId(497);
+ static constexpr const TSymbolUniqueId ftransform = TSymbolUniqueId(498);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x2_Float2x2 = TSymbolUniqueId(499);
+ static constexpr const TSymbolUniqueId pt50B = TSymbolUniqueId(500);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x3_Float3x3 = TSymbolUniqueId(501);
+ static constexpr const TSymbolUniqueId ptA0B = TSymbolUniqueId(502);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x4_Float4x4 = TSymbolUniqueId(503);
+ static constexpr const TSymbolUniqueId ptF0B = TSymbolUniqueId(504);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x3_Float2x3 = TSymbolUniqueId(505);
+ static constexpr const TSymbolUniqueId pt90B = TSymbolUniqueId(506);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x2_Float3x2 = TSymbolUniqueId(507);
+ static constexpr const TSymbolUniqueId pt60B = TSymbolUniqueId(508);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x4_Float2x4 = TSymbolUniqueId(509);
+ static constexpr const TSymbolUniqueId ptD0B = TSymbolUniqueId(510);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x2_Float4x2 = TSymbolUniqueId(511);
+ static constexpr const TSymbolUniqueId pt70B = TSymbolUniqueId(512);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x4_Float3x4 = TSymbolUniqueId(513);
+ static constexpr const TSymbolUniqueId ptE0B = TSymbolUniqueId(514);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x3_Float4x3 = TSymbolUniqueId(515);
+ static constexpr const TSymbolUniqueId ptB0B = TSymbolUniqueId(516);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float2 = TSymbolUniqueId(517);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float3 = TSymbolUniqueId(518);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float4 = TSymbolUniqueId(519);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float2 = TSymbolUniqueId(520);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float3 = TSymbolUniqueId(521);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float2 = TSymbolUniqueId(522);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float4 = TSymbolUniqueId(523);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float3 = TSymbolUniqueId(524);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float4 = TSymbolUniqueId(525);
+ static constexpr const TSymbolUniqueId transpose_Float2x2 = TSymbolUniqueId(526);
+ static constexpr const TSymbolUniqueId transpose_Float3x3 = TSymbolUniqueId(527);
+ static constexpr const TSymbolUniqueId transpose_Float4x4 = TSymbolUniqueId(528);
+ static constexpr const TSymbolUniqueId transpose_Float3x2 = TSymbolUniqueId(529);
+ static constexpr const TSymbolUniqueId transpose_Float2x3 = TSymbolUniqueId(530);
+ static constexpr const TSymbolUniqueId transpose_Float4x2 = TSymbolUniqueId(531);
+ static constexpr const TSymbolUniqueId transpose_Float2x4 = TSymbolUniqueId(532);
+ static constexpr const TSymbolUniqueId transpose_Float4x3 = TSymbolUniqueId(533);
+ static constexpr const TSymbolUniqueId transpose_Float3x4 = TSymbolUniqueId(534);
+ static constexpr const TSymbolUniqueId determinant_Float2x2 = TSymbolUniqueId(535);
+ static constexpr const TSymbolUniqueId determinant_Float3x3 = TSymbolUniqueId(536);
+ static constexpr const TSymbolUniqueId determinant_Float4x4 = TSymbolUniqueId(537);
+ static constexpr const TSymbolUniqueId inverse_Float2x2 = TSymbolUniqueId(538);
+ static constexpr const TSymbolUniqueId inverse_Float3x3 = TSymbolUniqueId(539);
+ static constexpr const TSymbolUniqueId inverse_Float4x4 = TSymbolUniqueId(540);
+ static constexpr const TSymbolUniqueId lessThan_Float2_Float2 = TSymbolUniqueId(541);
+ static constexpr const TSymbolUniqueId lessThan_Float3_Float3 = TSymbolUniqueId(542);
+ static constexpr const TSymbolUniqueId lessThan_Float4_Float4 = TSymbolUniqueId(543);
+ static constexpr const TSymbolUniqueId lessThan_Int2_Int2 = TSymbolUniqueId(544);
+ static constexpr const TSymbolUniqueId lessThan_Int3_Int3 = TSymbolUniqueId(545);
+ static constexpr const TSymbolUniqueId lessThan_Int4_Int4 = TSymbolUniqueId(546);
+ static constexpr const TSymbolUniqueId lessThan_UInt2_UInt2 = TSymbolUniqueId(547);
+ static constexpr const TSymbolUniqueId lessThan_UInt3_UInt3 = TSymbolUniqueId(548);
+ static constexpr const TSymbolUniqueId lessThan_UInt4_UInt4 = TSymbolUniqueId(549);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float2_Float2 = TSymbolUniqueId(550);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float3_Float3 = TSymbolUniqueId(551);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float4_Float4 = TSymbolUniqueId(552);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int2_Int2 = TSymbolUniqueId(553);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int3_Int3 = TSymbolUniqueId(554);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int4_Int4 = TSymbolUniqueId(555);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt2_UInt2 = TSymbolUniqueId(556);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt3_UInt3 = TSymbolUniqueId(557);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt4_UInt4 = TSymbolUniqueId(558);
+ static constexpr const TSymbolUniqueId greaterThan_Float2_Float2 = TSymbolUniqueId(559);
+ static constexpr const TSymbolUniqueId greaterThan_Float3_Float3 = TSymbolUniqueId(560);
+ static constexpr const TSymbolUniqueId greaterThan_Float4_Float4 = TSymbolUniqueId(561);
+ static constexpr const TSymbolUniqueId greaterThan_Int2_Int2 = TSymbolUniqueId(562);
+ static constexpr const TSymbolUniqueId greaterThan_Int3_Int3 = TSymbolUniqueId(563);
+ static constexpr const TSymbolUniqueId greaterThan_Int4_Int4 = TSymbolUniqueId(564);
+ static constexpr const TSymbolUniqueId greaterThan_UInt2_UInt2 = TSymbolUniqueId(565);
+ static constexpr const TSymbolUniqueId greaterThan_UInt3_UInt3 = TSymbolUniqueId(566);
+ static constexpr const TSymbolUniqueId greaterThan_UInt4_UInt4 = TSymbolUniqueId(567);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float2_Float2 = TSymbolUniqueId(568);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float3_Float3 = TSymbolUniqueId(569);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float4_Float4 = TSymbolUniqueId(570);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int2_Int2 = TSymbolUniqueId(571);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int3_Int3 = TSymbolUniqueId(572);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int4_Int4 = TSymbolUniqueId(573);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt2_UInt2 = TSymbolUniqueId(574);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt3_UInt3 = TSymbolUniqueId(575);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt4_UInt4 = TSymbolUniqueId(576);
+ static constexpr const TSymbolUniqueId equal_Float2_Float2 = TSymbolUniqueId(577);
+ static constexpr const TSymbolUniqueId equal_Float3_Float3 = TSymbolUniqueId(578);
+ static constexpr const TSymbolUniqueId equal_Float4_Float4 = TSymbolUniqueId(579);
+ static constexpr const TSymbolUniqueId equal_Int2_Int2 = TSymbolUniqueId(580);
+ static constexpr const TSymbolUniqueId equal_Int3_Int3 = TSymbolUniqueId(581);
+ static constexpr const TSymbolUniqueId equal_Int4_Int4 = TSymbolUniqueId(582);
+ static constexpr const TSymbolUniqueId equal_UInt2_UInt2 = TSymbolUniqueId(583);
+ static constexpr const TSymbolUniqueId equal_UInt3_UInt3 = TSymbolUniqueId(584);
+ static constexpr const TSymbolUniqueId equal_UInt4_UInt4 = TSymbolUniqueId(585);
+ static constexpr const TSymbolUniqueId equal_Bool2_Bool2 = TSymbolUniqueId(586);
+ static constexpr const TSymbolUniqueId equal_Bool3_Bool3 = TSymbolUniqueId(587);
+ static constexpr const TSymbolUniqueId equal_Bool4_Bool4 = TSymbolUniqueId(588);
+ static constexpr const TSymbolUniqueId notEqual_Float2_Float2 = TSymbolUniqueId(589);
+ static constexpr const TSymbolUniqueId notEqual_Float3_Float3 = TSymbolUniqueId(590);
+ static constexpr const TSymbolUniqueId notEqual_Float4_Float4 = TSymbolUniqueId(591);
+ static constexpr const TSymbolUniqueId notEqual_Int2_Int2 = TSymbolUniqueId(592);
+ static constexpr const TSymbolUniqueId notEqual_Int3_Int3 = TSymbolUniqueId(593);
+ static constexpr const TSymbolUniqueId notEqual_Int4_Int4 = TSymbolUniqueId(594);
+ static constexpr const TSymbolUniqueId notEqual_UInt2_UInt2 = TSymbolUniqueId(595);
+ static constexpr const TSymbolUniqueId notEqual_UInt3_UInt3 = TSymbolUniqueId(596);
+ static constexpr const TSymbolUniqueId notEqual_UInt4_UInt4 = TSymbolUniqueId(597);
+ static constexpr const TSymbolUniqueId notEqual_Bool2_Bool2 = TSymbolUniqueId(598);
+ static constexpr const TSymbolUniqueId notEqual_Bool3_Bool3 = TSymbolUniqueId(599);
+ static constexpr const TSymbolUniqueId notEqual_Bool4_Bool4 = TSymbolUniqueId(600);
+ static constexpr const TSymbolUniqueId any_Bool2 = TSymbolUniqueId(601);
+ static constexpr const TSymbolUniqueId any_Bool3 = TSymbolUniqueId(602);
+ static constexpr const TSymbolUniqueId any_Bool4 = TSymbolUniqueId(603);
+ static constexpr const TSymbolUniqueId all_Bool2 = TSymbolUniqueId(604);
+ static constexpr const TSymbolUniqueId all_Bool3 = TSymbolUniqueId(605);
+ static constexpr const TSymbolUniqueId all_Bool4 = TSymbolUniqueId(606);
+ static constexpr const TSymbolUniqueId notFunc_Bool2 = TSymbolUniqueId(607);
+ static constexpr const TSymbolUniqueId notFunc_Bool3 = TSymbolUniqueId(608);
+ static constexpr const TSymbolUniqueId notFunc_Bool4 = TSymbolUniqueId(609);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int1_Int1_Int1 = TSymbolUniqueId(610);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int2_Int1_Int1 = TSymbolUniqueId(611);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int3_Int1_Int1 = TSymbolUniqueId(612);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int4_Int1_Int1 = TSymbolUniqueId(613);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt1_Int1_Int1 = TSymbolUniqueId(614);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt2_Int1_Int1 = TSymbolUniqueId(615);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt3_Int1_Int1 = TSymbolUniqueId(616);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt4_Int1_Int1 = TSymbolUniqueId(617);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int1_Int1_Int1_Int1 =
+ TSymbolUniqueId(618);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int2_Int2_Int1_Int1 =
+ TSymbolUniqueId(619);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int3_Int3_Int1_Int1 =
+ TSymbolUniqueId(620);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int4_Int4_Int1_Int1 =
+ TSymbolUniqueId(621);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt1_UInt1_Int1_Int1 =
+ TSymbolUniqueId(622);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt2_UInt2_Int1_Int1 =
+ TSymbolUniqueId(623);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt3_UInt3_Int1_Int1 =
+ TSymbolUniqueId(624);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt4_UInt4_Int1_Int1 =
+ TSymbolUniqueId(625);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int1 = TSymbolUniqueId(626);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int2 = TSymbolUniqueId(627);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int3 = TSymbolUniqueId(628);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int4 = TSymbolUniqueId(629);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt1 = TSymbolUniqueId(630);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt2 = TSymbolUniqueId(631);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt3 = TSymbolUniqueId(632);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt4 = TSymbolUniqueId(633);
+ static constexpr const TSymbolUniqueId bitCount_Int1 = TSymbolUniqueId(634);
+ static constexpr const TSymbolUniqueId bitCount_Int2 = TSymbolUniqueId(635);
+ static constexpr const TSymbolUniqueId bitCount_Int3 = TSymbolUniqueId(636);
+ static constexpr const TSymbolUniqueId bitCount_Int4 = TSymbolUniqueId(637);
+ static constexpr const TSymbolUniqueId bitCount_UInt1 = TSymbolUniqueId(638);
+ static constexpr const TSymbolUniqueId bitCount_UInt2 = TSymbolUniqueId(639);
+ static constexpr const TSymbolUniqueId bitCount_UInt3 = TSymbolUniqueId(640);
+ static constexpr const TSymbolUniqueId bitCount_UInt4 = TSymbolUniqueId(641);
+ static constexpr const TSymbolUniqueId findLSB_Int1 = TSymbolUniqueId(642);
+ static constexpr const TSymbolUniqueId findLSB_Int2 = TSymbolUniqueId(643);
+ static constexpr const TSymbolUniqueId findLSB_Int3 = TSymbolUniqueId(644);
+ static constexpr const TSymbolUniqueId findLSB_Int4 = TSymbolUniqueId(645);
+ static constexpr const TSymbolUniqueId findLSB_UInt1 = TSymbolUniqueId(646);
+ static constexpr const TSymbolUniqueId findLSB_UInt2 = TSymbolUniqueId(647);
+ static constexpr const TSymbolUniqueId findLSB_UInt3 = TSymbolUniqueId(648);
+ static constexpr const TSymbolUniqueId findLSB_UInt4 = TSymbolUniqueId(649);
+ static constexpr const TSymbolUniqueId findMSB_Int1 = TSymbolUniqueId(650);
+ static constexpr const TSymbolUniqueId findMSB_Int2 = TSymbolUniqueId(651);
+ static constexpr const TSymbolUniqueId findMSB_Int3 = TSymbolUniqueId(652);
+ static constexpr const TSymbolUniqueId findMSB_Int4 = TSymbolUniqueId(653);
+ static constexpr const TSymbolUniqueId findMSB_UInt1 = TSymbolUniqueId(654);
+ static constexpr const TSymbolUniqueId findMSB_UInt2 = TSymbolUniqueId(655);
+ static constexpr const TSymbolUniqueId findMSB_UInt3 = TSymbolUniqueId(656);
+ static constexpr const TSymbolUniqueId findMSB_UInt4 = TSymbolUniqueId(657);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt1_UInt1_UInt1 = TSymbolUniqueId(658);
+ static constexpr const TSymbolUniqueId pt_o_00E = TSymbolUniqueId(659);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt2_UInt2_UInt2 = TSymbolUniqueId(660);
+ static constexpr const TSymbolUniqueId pt_o_10E = TSymbolUniqueId(661);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt3_UInt3_UInt3 = TSymbolUniqueId(662);
+ static constexpr const TSymbolUniqueId pt_o_20E = TSymbolUniqueId(663);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt4_UInt4_UInt4 = TSymbolUniqueId(664);
+ static constexpr const TSymbolUniqueId pt_o_30E = TSymbolUniqueId(665);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt1_UInt1_UInt1 = TSymbolUniqueId(666);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt2_UInt2_UInt2 = TSymbolUniqueId(667);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt3_UInt3_UInt3 = TSymbolUniqueId(668);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt4_UInt4_UInt4 = TSymbolUniqueId(669);
+ static constexpr const TSymbolUniqueId umulExtended_UInt1_UInt1_UInt1_UInt1 =
+ TSymbolUniqueId(670);
+ static constexpr const TSymbolUniqueId umulExtended_UInt2_UInt2_UInt2_UInt2 =
+ TSymbolUniqueId(671);
+ static constexpr const TSymbolUniqueId umulExtended_UInt3_UInt3_UInt3_UInt3 =
+ TSymbolUniqueId(672);
+ static constexpr const TSymbolUniqueId umulExtended_UInt4_UInt4_UInt4_UInt4 =
+ TSymbolUniqueId(673);
+ static constexpr const TSymbolUniqueId imulExtended_Int1_Int1_Int1_Int1 = TSymbolUniqueId(674);
+ static constexpr const TSymbolUniqueId imulExtended_Int2_Int2_Int2_Int2 = TSymbolUniqueId(675);
+ static constexpr const TSymbolUniqueId imulExtended_Int3_Int3_Int3_Int3 = TSymbolUniqueId(676);
+ static constexpr const TSymbolUniqueId imulExtended_Int4_Int4_Int4_Int4 = TSymbolUniqueId(677);
+ static constexpr const TSymbolUniqueId texture2D_Sampler2D1_Float2 = TSymbolUniqueId(678);
+ static constexpr const TSymbolUniqueId pt00I = TSymbolUniqueId(679);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float3 = TSymbolUniqueId(680);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float4 = TSymbolUniqueId(681);
+ static constexpr const TSymbolUniqueId textureCube_SamplerCube1_Float3 = TSymbolUniqueId(682);
+ static constexpr const TSymbolUniqueId pt00K = TSymbolUniqueId(683);
+ static constexpr const TSymbolUniqueId texture1D_Sampler1D1_Float1 = TSymbolUniqueId(684);
+ static constexpr const TSymbolUniqueId pt00g = TSymbolUniqueId(685);
+ static constexpr const TSymbolUniqueId texture1DProj_Sampler1D1_Float2 = TSymbolUniqueId(686);
+ static constexpr const TSymbolUniqueId texture1DProj_Sampler1D1_Float4 = TSymbolUniqueId(687);
+ static constexpr const TSymbolUniqueId texture3D_Sampler3D1_Float3 = TSymbolUniqueId(688);
+ static constexpr const TSymbolUniqueId pt00J = TSymbolUniqueId(689);
+ static constexpr const TSymbolUniqueId texture3DProj_Sampler3D1_Float4 = TSymbolUniqueId(690);
+ static constexpr const TSymbolUniqueId shadow1D_Sampler1DShadow1_Float3 = TSymbolUniqueId(691);
+ static constexpr const TSymbolUniqueId pt00m = TSymbolUniqueId(692);
+ static constexpr const TSymbolUniqueId shadow1DProj_Sampler1DShadow1_Float4 =
+ TSymbolUniqueId(693);
+ static constexpr const TSymbolUniqueId shadow2D_Sampler2DShadow1_Float3 = TSymbolUniqueId(694);
+ static constexpr const TSymbolUniqueId pt00d = TSymbolUniqueId(695);
+ static constexpr const TSymbolUniqueId shadow2DProj_Sampler2DShadow1_Float4 =
+ TSymbolUniqueId(696);
+ static constexpr const TSymbolUniqueId shadow2DEXT_Sampler2DShadow1_Float3 =
+ TSymbolUniqueId(697);
+ static constexpr const TSymbolUniqueId shadow2DProjEXT_Sampler2DShadow1_Float4 =
+ TSymbolUniqueId(698);
+ static constexpr const TSymbolUniqueId texture2D_SamplerExternalOES1_Float2 =
+ TSymbolUniqueId(699);
+ static constexpr const TSymbolUniqueId pt00M = TSymbolUniqueId(700);
+ static constexpr const TSymbolUniqueId texture2DProj_SamplerExternalOES1_Float3 =
+ TSymbolUniqueId(701);
+ static constexpr const TSymbolUniqueId texture2DProj_SamplerExternalOES1_Float4 =
+ TSymbolUniqueId(702);
+ static constexpr const TSymbolUniqueId texture2DRect_Sampler2DRect1_Float2 =
+ TSymbolUniqueId(703);
+ static constexpr const TSymbolUniqueId pt00O = TSymbolUniqueId(704);
+ static constexpr const TSymbolUniqueId texture2DRectProj_Sampler2DRect1_Float3 =
+ TSymbolUniqueId(705);
+ static constexpr const TSymbolUniqueId texture2DRectProj_Sampler2DRect1_Float4 =
+ TSymbolUniqueId(706);
+ static constexpr const TSymbolUniqueId texture2DGradEXT_Sampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(707);
+ static constexpr const TSymbolUniqueId texture2DProjGradEXT_Sampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(708);
+ static constexpr const TSymbolUniqueId texture2DProjGradEXT_Sampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(709);
+ static constexpr const TSymbolUniqueId textureCubeGradEXT_SamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(710);
+ static constexpr const TSymbolUniqueId textureVideoWEBGL_SamplerVideoWEBGL1_Float2 =
+ TSymbolUniqueId(711);
+ static constexpr const TSymbolUniqueId pt00y = TSymbolUniqueId(712);
+ static constexpr const TSymbolUniqueId texture2D_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(713);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(714);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(715);
+ static constexpr const TSymbolUniqueId textureCube_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(716);
+ static constexpr const TSymbolUniqueId texture3D_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(717);
+ static constexpr const TSymbolUniqueId texture3DProj_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(718);
+ static constexpr const TSymbolUniqueId texture1D_Sampler1D1_Float1_Float1 =
+ TSymbolUniqueId(719);
+ static constexpr const TSymbolUniqueId texture1DProj_Sampler1D1_Float2_Float1 =
+ TSymbolUniqueId(720);
+ static constexpr const TSymbolUniqueId texture1DProj_Sampler1D1_Float4_Float1 =
+ TSymbolUniqueId(721);
+ static constexpr const TSymbolUniqueId shadow1D_Sampler1DShadow1_Float3_Float1 =
+ TSymbolUniqueId(722);
+ static constexpr const TSymbolUniqueId shadow1DProj_Sampler1DShadow1_Float4_Float1 =
+ TSymbolUniqueId(723);
+ static constexpr const TSymbolUniqueId shadow2D_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(724);
+ static constexpr const TSymbolUniqueId shadow2DProj_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(725);
+ static constexpr const TSymbolUniqueId texture2DLod_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(726);
+ static constexpr const TSymbolUniqueId texture2DProjLod_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(727);
+ static constexpr const TSymbolUniqueId texture2DProjLod_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(728);
+ static constexpr const TSymbolUniqueId textureCubeLod_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(729);
+ static constexpr const TSymbolUniqueId texture1DLod_Sampler1D1_Float1_Float1 =
+ TSymbolUniqueId(730);
+ static constexpr const TSymbolUniqueId texture1DProjLod_Sampler1D1_Float2_Float1 =
+ TSymbolUniqueId(731);
+ static constexpr const TSymbolUniqueId texture1DProjLod_Sampler1D1_Float4_Float1 =
+ TSymbolUniqueId(732);
+ static constexpr const TSymbolUniqueId shadow1DLod_Sampler1DShadow1_Float3_Float1 =
+ TSymbolUniqueId(733);
+ static constexpr const TSymbolUniqueId shadow1DProjLod_Sampler1DShadow1_Float4_Float1 =
+ TSymbolUniqueId(734);
+ static constexpr const TSymbolUniqueId shadow2DLod_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(735);
+ static constexpr const TSymbolUniqueId shadow2DProjLod_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(736);
+ static constexpr const TSymbolUniqueId texture3DLod_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(737);
+ static constexpr const TSymbolUniqueId texture3DProjLod_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(738);
+ static constexpr const TSymbolUniqueId texture2DLodEXT_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(739);
+ static constexpr const TSymbolUniqueId texture2DProjLodEXT_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(740);
+ static constexpr const TSymbolUniqueId texture2DProjLodEXT_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(741);
+ static constexpr const TSymbolUniqueId textureCubeLodEXT_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(742);
+ static constexpr const TSymbolUniqueId texture_Sampler2D1_Float2 = TSymbolUniqueId(743);
+ static constexpr const TSymbolUniqueId texture_ISampler2D1_Float2 = TSymbolUniqueId(744);
+ static constexpr const TSymbolUniqueId pt00R = TSymbolUniqueId(745);
+ static constexpr const TSymbolUniqueId texture_USampler2D1_Float2 = TSymbolUniqueId(746);
+ static constexpr const TSymbolUniqueId pt00X = TSymbolUniqueId(747);
+ static constexpr const TSymbolUniqueId texture_Sampler3D1_Float3 = TSymbolUniqueId(748);
+ static constexpr const TSymbolUniqueId texture_ISampler3D1_Float3 = TSymbolUniqueId(749);
+ static constexpr const TSymbolUniqueId pt00S = TSymbolUniqueId(750);
+ static constexpr const TSymbolUniqueId texture_USampler3D1_Float3 = TSymbolUniqueId(751);
+ static constexpr const TSymbolUniqueId pt00Y = TSymbolUniqueId(752);
+ static constexpr const TSymbolUniqueId texture_SamplerCube1_Float3 = TSymbolUniqueId(753);
+ static constexpr const TSymbolUniqueId texture_ISamplerCube1_Float3 = TSymbolUniqueId(754);
+ static constexpr const TSymbolUniqueId pt00T = TSymbolUniqueId(755);
+ static constexpr const TSymbolUniqueId texture_USamplerCube1_Float3 = TSymbolUniqueId(756);
+ static constexpr const TSymbolUniqueId pt00Z = TSymbolUniqueId(757);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArray1_Float3 = TSymbolUniqueId(758);
+ static constexpr const TSymbolUniqueId pt00L = TSymbolUniqueId(759);
+ static constexpr const TSymbolUniqueId texture_ISampler2DArray1_Float3 = TSymbolUniqueId(760);
+ static constexpr const TSymbolUniqueId pt00U = TSymbolUniqueId(761);
+ static constexpr const TSymbolUniqueId texture_USampler2DArray1_Float3 = TSymbolUniqueId(762);
+ static constexpr const TSymbolUniqueId pt00a = TSymbolUniqueId(763);
+ static constexpr const TSymbolUniqueId texture_Sampler2DShadow1_Float3 = TSymbolUniqueId(764);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeShadow1_Float4 = TSymbolUniqueId(765);
+ static constexpr const TSymbolUniqueId pt00e = TSymbolUniqueId(766);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArrayShadow1_Float4 =
+ TSymbolUniqueId(767);
+ static constexpr const TSymbolUniqueId pt00f = TSymbolUniqueId(768);
+ static constexpr const TSymbolUniqueId texture_Sampler1D1_Float1 = TSymbolUniqueId(769);
+ static constexpr const TSymbolUniqueId texture_ISampler1D1_Float1 = TSymbolUniqueId(770);
+ static constexpr const TSymbolUniqueId pt00o = TSymbolUniqueId(771);
+ static constexpr const TSymbolUniqueId texture_USampler1D1_Float1 = TSymbolUniqueId(772);
+ static constexpr const TSymbolUniqueId pt00t = TSymbolUniqueId(773);
+ static constexpr const TSymbolUniqueId texture_Sampler1DShadow1_Float3 = TSymbolUniqueId(774);
+ static constexpr const TSymbolUniqueId texture_Sampler1DArray1_Float3 = TSymbolUniqueId(775);
+ static constexpr const TSymbolUniqueId pt00h = TSymbolUniqueId(776);
+ static constexpr const TSymbolUniqueId texture_ISampler1DArray1_Float3 = TSymbolUniqueId(777);
+ static constexpr const TSymbolUniqueId pt00p = TSymbolUniqueId(778);
+ static constexpr const TSymbolUniqueId texture_USampler1DArray1_Float3 = TSymbolUniqueId(779);
+ static constexpr const TSymbolUniqueId pt00u = TSymbolUniqueId(780);
+ static constexpr const TSymbolUniqueId texture_Sampler1DArrayShadow1_Float3 =
+ TSymbolUniqueId(781);
+ static constexpr const TSymbolUniqueId pt00i = TSymbolUniqueId(782);
+ static constexpr const TSymbolUniqueId texture_Sampler2DRect1_Float2 = TSymbolUniqueId(783);
+ static constexpr const TSymbolUniqueId texture_ISampler2DRect1_Float2 = TSymbolUniqueId(784);
+ static constexpr const TSymbolUniqueId pt00q = TSymbolUniqueId(785);
+ static constexpr const TSymbolUniqueId texture_USampler2DRect1_Float2 = TSymbolUniqueId(786);
+ static constexpr const TSymbolUniqueId pt00v = TSymbolUniqueId(787);
+ static constexpr const TSymbolUniqueId texture_Sampler2DRectShadow1_Float3 =
+ TSymbolUniqueId(788);
+ static constexpr const TSymbolUniqueId pt00n = TSymbolUniqueId(789);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArray1_Float4 = TSymbolUniqueId(790);
+ static constexpr const TSymbolUniqueId pt00k = TSymbolUniqueId(791);
+ static constexpr const TSymbolUniqueId texture_ISamplerCubeArray1_Float4 = TSymbolUniqueId(792);
+ static constexpr const TSymbolUniqueId pt00s = TSymbolUniqueId(793);
+ static constexpr const TSymbolUniqueId texture_USamplerCubeArray1_Float4 = TSymbolUniqueId(794);
+ static constexpr const TSymbolUniqueId pt00x = TSymbolUniqueId(795);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(796);
+ static constexpr const TSymbolUniqueId pt00l = TSymbolUniqueId(797);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(798);
+ static constexpr const TSymbolUniqueId textureExt_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(799);
+ static constexpr const TSymbolUniqueId textureExt_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(800);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(801);
+ static constexpr const TSymbolUniqueId texture_SamplerExternalOES1_Float2 =
+ TSymbolUniqueId(802);
+ static constexpr const TSymbolUniqueId texture_SamplerExternal2DY2YEXT1_Float2 =
+ TSymbolUniqueId(803);
+ static constexpr const TSymbolUniqueId pt00N = TSymbolUniqueId(804);
+ static constexpr const TSymbolUniqueId texture_SamplerVideoWEBGL1_Float2 = TSymbolUniqueId(805);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float3 = TSymbolUniqueId(806);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float3 = TSymbolUniqueId(807);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float3 = TSymbolUniqueId(808);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float4 = TSymbolUniqueId(809);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float4 = TSymbolUniqueId(810);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float4 = TSymbolUniqueId(811);
+ static constexpr const TSymbolUniqueId textureProj_Sampler3D1_Float4 = TSymbolUniqueId(812);
+ static constexpr const TSymbolUniqueId textureProj_ISampler3D1_Float4 = TSymbolUniqueId(813);
+ static constexpr const TSymbolUniqueId textureProj_USampler3D1_Float4 = TSymbolUniqueId(814);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DShadow1_Float4 =
+ TSymbolUniqueId(815);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1D1_Float2 = TSymbolUniqueId(816);
+ static constexpr const TSymbolUniqueId textureProj_ISampler1D1_Float2 = TSymbolUniqueId(817);
+ static constexpr const TSymbolUniqueId textureProj_USampler1D1_Float2 = TSymbolUniqueId(818);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1D1_Float4 = TSymbolUniqueId(819);
+ static constexpr const TSymbolUniqueId textureProj_ISampler1D1_Float4 = TSymbolUniqueId(820);
+ static constexpr const TSymbolUniqueId textureProj_USampler1D1_Float4 = TSymbolUniqueId(821);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1DShadow1_Float4 =
+ TSymbolUniqueId(822);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DRect1_Float3 = TSymbolUniqueId(823);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2DRect1_Float3 =
+ TSymbolUniqueId(824);
+ static constexpr const TSymbolUniqueId textureProj_USampler2DRect1_Float3 =
+ TSymbolUniqueId(825);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DRect1_Float4 = TSymbolUniqueId(826);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2DRect1_Float4 =
+ TSymbolUniqueId(827);
+ static constexpr const TSymbolUniqueId textureProj_USampler2DRect1_Float4 =
+ TSymbolUniqueId(828);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DRectShadow1_Float4 =
+ TSymbolUniqueId(829);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float3 =
+ TSymbolUniqueId(830);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float4 =
+ TSymbolUniqueId(831);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float3 =
+ TSymbolUniqueId(832);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float4 =
+ TSymbolUniqueId(833);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(834);
+ static constexpr const TSymbolUniqueId textureLod_ISampler2D1_Float2_Float1 =
+ TSymbolUniqueId(835);
+ static constexpr const TSymbolUniqueId textureLod_USampler2D1_Float2_Float1 =
+ TSymbolUniqueId(836);
+ static constexpr const TSymbolUniqueId textureLod_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(837);
+ static constexpr const TSymbolUniqueId textureLod_ISampler3D1_Float3_Float1 =
+ TSymbolUniqueId(838);
+ static constexpr const TSymbolUniqueId textureLod_USampler3D1_Float3_Float1 =
+ TSymbolUniqueId(839);
+ static constexpr const TSymbolUniqueId textureLod_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(840);
+ static constexpr const TSymbolUniqueId textureLod_ISamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(841);
+ static constexpr const TSymbolUniqueId textureLod_USamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(842);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(843);
+ static constexpr const TSymbolUniqueId textureLod_ISampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(844);
+ static constexpr const TSymbolUniqueId textureLod_USampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(845);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(846);
+ static constexpr const TSymbolUniqueId textureLod_Sampler1D1_Float1_Float1 =
+ TSymbolUniqueId(847);
+ static constexpr const TSymbolUniqueId textureLod_ISampler1D1_Float1_Float1 =
+ TSymbolUniqueId(848);
+ static constexpr const TSymbolUniqueId textureLod_USampler1D1_Float1_Float1 =
+ TSymbolUniqueId(849);
+ static constexpr const TSymbolUniqueId textureLod_Sampler1DShadow1_Float3_Float1 =
+ TSymbolUniqueId(850);
+ static constexpr const TSymbolUniqueId textureLod_Sampler1DArray1_Float2_Float1 =
+ TSymbolUniqueId(851);
+ static constexpr const TSymbolUniqueId textureLod_ISampler1DArray1_Float2_Float1 =
+ TSymbolUniqueId(852);
+ static constexpr const TSymbolUniqueId textureLod_USampler1DArray1_Float2_Float1 =
+ TSymbolUniqueId(853);
+ static constexpr const TSymbolUniqueId textureLod_Sampler1DArrayShadow1_Float3_Float1 =
+ TSymbolUniqueId(854);
+ static constexpr const TSymbolUniqueId textureLod_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(855);
+ static constexpr const TSymbolUniqueId textureLod_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(856);
+ static constexpr const TSymbolUniqueId textureLod_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(857);
+ static constexpr const TSymbolUniqueId textureLodExt_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(858);
+ static constexpr const TSymbolUniqueId textureLodExt_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(859);
+ static constexpr const TSymbolUniqueId textureLodExt_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(860);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2D1_Int1 = TSymbolUniqueId(861);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2D1_Int1 = TSymbolUniqueId(862);
+ static constexpr const TSymbolUniqueId textureSize_USampler2D1_Int1 = TSymbolUniqueId(863);
+ static constexpr const TSymbolUniqueId textureSize_Sampler3D1_Int1 = TSymbolUniqueId(864);
+ static constexpr const TSymbolUniqueId textureSize_ISampler3D1_Int1 = TSymbolUniqueId(865);
+ static constexpr const TSymbolUniqueId textureSize_USampler3D1_Int1 = TSymbolUniqueId(866);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCube1_Int1 = TSymbolUniqueId(867);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerCube1_Int1 = TSymbolUniqueId(868);
+ static constexpr const TSymbolUniqueId textureSize_USamplerCube1_Int1 = TSymbolUniqueId(869);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DArray1_Int1 = TSymbolUniqueId(870);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DArray1_Int1 = TSymbolUniqueId(871);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DArray1_Int1 = TSymbolUniqueId(872);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DShadow1_Int1 = TSymbolUniqueId(873);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeShadow1_Int1 =
+ TSymbolUniqueId(874);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DArrayShadow1_Int1 =
+ TSymbolUniqueId(875);
+ static constexpr const TSymbolUniqueId textureSize_Sampler1D1_Int1 = TSymbolUniqueId(876);
+ static constexpr const TSymbolUniqueId textureSize_ISampler1D1_Int1 = TSymbolUniqueId(877);
+ static constexpr const TSymbolUniqueId textureSize_USampler1D1_Int1 = TSymbolUniqueId(878);
+ static constexpr const TSymbolUniqueId textureSize_Sampler1DShadow1_Int1 = TSymbolUniqueId(879);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeArray1_Int1 =
+ TSymbolUniqueId(880);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerCubeArray1_Int1 =
+ TSymbolUniqueId(881);
+ static constexpr const TSymbolUniqueId textureSize_USamplerCubeArray1_Int1 =
+ TSymbolUniqueId(882);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeArrayShadow1_Int1 =
+ TSymbolUniqueId(883);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerCubeArray1_Int1 =
+ TSymbolUniqueId(884);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISamplerCubeArray1_Int1 =
+ TSymbolUniqueId(885);
+ static constexpr const TSymbolUniqueId textureSizeExt_USamplerCubeArray1_Int1 =
+ TSymbolUniqueId(886);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerCubeArrayShadow1_Int1 =
+ TSymbolUniqueId(887);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DRect1 = TSymbolUniqueId(888);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DRect1 = TSymbolUniqueId(889);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DRect1 = TSymbolUniqueId(890);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DRectShadow1 = TSymbolUniqueId(891);
+ static constexpr const TSymbolUniqueId textureSize_Sampler1DArray1_Int1 = TSymbolUniqueId(892);
+ static constexpr const TSymbolUniqueId textureSize_ISampler1DArray1_Int1 = TSymbolUniqueId(893);
+ static constexpr const TSymbolUniqueId textureSize_USampler1DArray1_Int1 = TSymbolUniqueId(894);
+ static constexpr const TSymbolUniqueId textureSize_Sampler1DArrayShadow1_Int1 =
+ TSymbolUniqueId(895);
+ static constexpr const TSymbolUniqueId textureSize_SamplerBuffer1 = TSymbolUniqueId(896);
+ static constexpr const TSymbolUniqueId pt00j = TSymbolUniqueId(897);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerBuffer1 = TSymbolUniqueId(898);
+ static constexpr const TSymbolUniqueId pt00r = TSymbolUniqueId(899);
+ static constexpr const TSymbolUniqueId textureSize_USamplerBuffer1 = TSymbolUniqueId(900);
+ static constexpr const TSymbolUniqueId pt00w = TSymbolUniqueId(901);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerBuffer1 = TSymbolUniqueId(902);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISamplerBuffer1 = TSymbolUniqueId(903);
+ static constexpr const TSymbolUniqueId textureSizeExt_USamplerBuffer1 = TSymbolUniqueId(904);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DMS1 = TSymbolUniqueId(905);
+ static constexpr const TSymbolUniqueId pt00P = TSymbolUniqueId(906);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DMS1 = TSymbolUniqueId(907);
+ static constexpr const TSymbolUniqueId pt00V = TSymbolUniqueId(908);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DMS1 = TSymbolUniqueId(909);
+ static constexpr const TSymbolUniqueId pt00b = TSymbolUniqueId(910);
+ static constexpr const TSymbolUniqueId textureSizeExt_Sampler2DMS1 = TSymbolUniqueId(911);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISampler2DMS1 = TSymbolUniqueId(912);
+ static constexpr const TSymbolUniqueId textureSizeExt_USampler2DMS1 = TSymbolUniqueId(913);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DMSArray1 = TSymbolUniqueId(914);
+ static constexpr const TSymbolUniqueId pt00Q = TSymbolUniqueId(915);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DMSArray1 = TSymbolUniqueId(916);
+ static constexpr const TSymbolUniqueId pt00W = TSymbolUniqueId(917);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DMSArray1 = TSymbolUniqueId(918);
+ static constexpr const TSymbolUniqueId pt00c = TSymbolUniqueId(919);
+ static constexpr const TSymbolUniqueId textureSizeExt_Sampler2DMSArray1 = TSymbolUniqueId(920);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISampler2DMSArray1 = TSymbolUniqueId(921);
+ static constexpr const TSymbolUniqueId textureSizeExt_USampler2DMSArray1 = TSymbolUniqueId(922);
+ static constexpr const TSymbolUniqueId textureSize_SamplerExternalOES1_Int1 =
+ TSymbolUniqueId(923);
+ static constexpr const TSymbolUniqueId textureSize_SamplerExternal2DY2YEXT1_Int1 =
+ TSymbolUniqueId(924);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(925);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler2D1_Float3_Float1 =
+ TSymbolUniqueId(926);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler2D1_Float3_Float1 =
+ TSymbolUniqueId(927);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(928);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler2D1_Float4_Float1 =
+ TSymbolUniqueId(929);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler2D1_Float4_Float1 =
+ TSymbolUniqueId(930);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(931);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler3D1_Float4_Float1 =
+ TSymbolUniqueId(932);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler3D1_Float4_Float1 =
+ TSymbolUniqueId(933);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(934);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler1D1_Float2_Float1 =
+ TSymbolUniqueId(935);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler1D1_Float2_Float1 =
+ TSymbolUniqueId(936);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler1D1_Float2_Float1 =
+ TSymbolUniqueId(937);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler1D1_Float4_Float1 =
+ TSymbolUniqueId(938);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler1D1_Float4_Float1 =
+ TSymbolUniqueId(939);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler1D1_Float4_Float1 =
+ TSymbolUniqueId(940);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler1DShadow1_Float4_Float1 =
+ TSymbolUniqueId(941);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2D1_Int2_Int1 = TSymbolUniqueId(942);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2D1_Int2_Int1 = TSymbolUniqueId(943);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2D1_Int2_Int1 = TSymbolUniqueId(944);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler3D1_Int3_Int1 = TSymbolUniqueId(945);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler3D1_Int3_Int1 = TSymbolUniqueId(946);
+ static constexpr const TSymbolUniqueId texelFetch_USampler3D1_Int3_Int1 = TSymbolUniqueId(947);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(948);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(949);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(950);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler1D1_Int1_Int1 = TSymbolUniqueId(951);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler1D1_Int1_Int1 = TSymbolUniqueId(952);
+ static constexpr const TSymbolUniqueId texelFetch_USampler1D1_Int1_Int1 = TSymbolUniqueId(953);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DRect1_Int2 = TSymbolUniqueId(954);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DRect1_Int2 = TSymbolUniqueId(955);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DRect1_Int2 = TSymbolUniqueId(956);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler1DArray1_Int2_Int1 =
+ TSymbolUniqueId(957);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler1DArray1_Int2_Int1 =
+ TSymbolUniqueId(958);
+ static constexpr const TSymbolUniqueId texelFetch_USampler1DArray1_Int2_Int1 =
+ TSymbolUniqueId(959);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerBuffer1_Int1 = TSymbolUniqueId(960);
+ static constexpr const TSymbolUniqueId texelFetch_ISamplerBuffer1_Int1 = TSymbolUniqueId(961);
+ static constexpr const TSymbolUniqueId texelFetch_USamplerBuffer1_Int1 = TSymbolUniqueId(962);
+ static constexpr const TSymbolUniqueId texelFetchExt_SamplerBuffer1_Int1 = TSymbolUniqueId(963);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISamplerBuffer1_Int1 =
+ TSymbolUniqueId(964);
+ static constexpr const TSymbolUniqueId texelFetchExt_USamplerBuffer1_Int1 =
+ TSymbolUniqueId(965);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DMS1_Int2_Int1 = TSymbolUniqueId(966);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(967);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(968);
+ static constexpr const TSymbolUniqueId texelFetchExt_Sampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(969);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(970);
+ static constexpr const TSymbolUniqueId texelFetchExt_USampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(971);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(972);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(973);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(974);
+ static constexpr const TSymbolUniqueId texelFetchExt_Sampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(975);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(976);
+ static constexpr const TSymbolUniqueId texelFetchExt_USampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(977);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerExternalOES1_Int2_Int1 =
+ TSymbolUniqueId(978);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerExternal2DY2YEXT1_Int2_Int1 =
+ TSymbolUniqueId(979);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(980);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(981);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(982);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(983);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(984);
+ static constexpr const TSymbolUniqueId textureGrad_USampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(985);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(986);
+ static constexpr const TSymbolUniqueId textureGrad_ISamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(987);
+ static constexpr const TSymbolUniqueId textureGrad_USamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(988);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2D1_Float1_Float1_Float1 =
+ TSymbolUniqueId(989);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2D1_Float1_Float1_Float1 =
+ TSymbolUniqueId(990);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2D1_Float1_Float1_Float1 =
+ TSymbolUniqueId(991);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DRect1_Float2_Float2_Float2 =
+ TSymbolUniqueId(992);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2DRect1_Float2_Float2_Float2 =
+ TSymbolUniqueId(993);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2DRect1_Float2_Float2_Float2 =
+ TSymbolUniqueId(994);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DRectShadow1_Float3_Float2_Float2 =
+ TSymbolUniqueId(995);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DShadow1_Float3_Float2_Float2 =
+ TSymbolUniqueId(996);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCubeShadow1_Float4_Float3_Float3 =
+ TSymbolUniqueId(997);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(998);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(999);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1000);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DArrayShadow1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1001);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler1DShadow1_Float3_Float1_Float1 =
+ TSymbolUniqueId(1002);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler1DArray1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1003);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler1DArray1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1004);
+ static constexpr const TSymbolUniqueId textureGrad_USampler1DArray1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1005);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler1DArrayShadow1_Float3_Float1_Float1 =
+ TSymbolUniqueId(1006);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1007);
+ static constexpr const TSymbolUniqueId textureGrad_ISamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1008);
+ static constexpr const TSymbolUniqueId textureGrad_USamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1009);
+ static constexpr const TSymbolUniqueId textureGradExt_SamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1010);
+ static constexpr const TSymbolUniqueId textureGradExt_ISamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1011);
+ static constexpr const TSymbolUniqueId textureGradExt_USamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1012);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1013);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1014);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1015);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1016);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1017);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1018);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1019);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1020);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1021);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2DShadow1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1022);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler1D1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1023);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler1D1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1024);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler1D1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1025);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler1D1_Float4_Float1_Float1 =
+ TSymbolUniqueId(1026);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler1D1_Float4_Float1_Float1 =
+ TSymbolUniqueId(1027);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler1D1_Float4_Float1_Float1 =
+ TSymbolUniqueId(1028);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler1DShadow1_Float4_Float1_Float1 =
+ TSymbolUniqueId(1029);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2DRect1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1030);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2DRect1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1031);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2DRect1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1032);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2DRect1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1033);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2DRect1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1034);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2DRect1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1035);
+ static constexpr const TSymbolUniqueId
+ textureProjGrad_Sampler2DRectShadow1_Float4_Float2_Float2 = TSymbolUniqueId(1036);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler1D1 = TSymbolUniqueId(1037);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISampler1D1 = TSymbolUniqueId(1038);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USampler1D1 = TSymbolUniqueId(1039);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler2D1 = TSymbolUniqueId(1040);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISampler2D1 = TSymbolUniqueId(1041);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USampler2D1 = TSymbolUniqueId(1042);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler3D1 = TSymbolUniqueId(1043);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISampler3D1 = TSymbolUniqueId(1044);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USampler3D1 = TSymbolUniqueId(1045);
+ static constexpr const TSymbolUniqueId textureQueryLevels_SamplerCube1 = TSymbolUniqueId(1046);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISamplerCube1 = TSymbolUniqueId(1047);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USamplerCube1 = TSymbolUniqueId(1048);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler1DArray1 =
+ TSymbolUniqueId(1049);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISampler1DArray1 =
+ TSymbolUniqueId(1050);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USampler1DArray1 =
+ TSymbolUniqueId(1051);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler2DArray1 =
+ TSymbolUniqueId(1052);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISampler2DArray1 =
+ TSymbolUniqueId(1053);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USampler2DArray1 =
+ TSymbolUniqueId(1054);
+ static constexpr const TSymbolUniqueId textureQueryLevels_SamplerCubeArray1 =
+ TSymbolUniqueId(1055);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISamplerCubeArray1 =
+ TSymbolUniqueId(1056);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USamplerCubeArray1 =
+ TSymbolUniqueId(1057);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler1DShadow1 =
+ TSymbolUniqueId(1058);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler2DShadow1 =
+ TSymbolUniqueId(1059);
+ static constexpr const TSymbolUniqueId textureQueryLevels_SamplerCubeShadow1 =
+ TSymbolUniqueId(1060);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler1DArrayShadow1 =
+ TSymbolUniqueId(1061);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler2DArrayShadow1 =
+ TSymbolUniqueId(1062);
+ static constexpr const TSymbolUniqueId textureQueryLevels_SamplerCubeArrayShadow1 =
+ TSymbolUniqueId(1063);
+ static constexpr const TSymbolUniqueId textureSamples_Sampler2DMS1 = TSymbolUniqueId(1064);
+ static constexpr const TSymbolUniqueId textureSamples_ISampler2DMS1 = TSymbolUniqueId(1065);
+ static constexpr const TSymbolUniqueId textureSamples_USampler2DMS1 = TSymbolUniqueId(1066);
+ static constexpr const TSymbolUniqueId textureSamples_Sampler2DMSArray1 = TSymbolUniqueId(1067);
+ static constexpr const TSymbolUniqueId textureSamples_ISampler2DMSArray1 =
+ TSymbolUniqueId(1068);
+ static constexpr const TSymbolUniqueId textureSamples_USampler2DMSArray1 =
+ TSymbolUniqueId(1069);
+ static constexpr const TSymbolUniqueId texture_Sampler2D1_Float2_Float1 = TSymbolUniqueId(1070);
+ static constexpr const TSymbolUniqueId texture_ISampler2D1_Float2_Float1 =
+ TSymbolUniqueId(1071);
+ static constexpr const TSymbolUniqueId texture_USampler2D1_Float2_Float1 =
+ TSymbolUniqueId(1072);
+ static constexpr const TSymbolUniqueId texture_Sampler3D1_Float3_Float1 = TSymbolUniqueId(1073);
+ static constexpr const TSymbolUniqueId texture_ISampler3D1_Float3_Float1 =
+ TSymbolUniqueId(1074);
+ static constexpr const TSymbolUniqueId texture_USampler3D1_Float3_Float1 =
+ TSymbolUniqueId(1075);
+ static constexpr const TSymbolUniqueId texture_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(1076);
+ static constexpr const TSymbolUniqueId texture_ISamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(1077);
+ static constexpr const TSymbolUniqueId texture_USamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(1078);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(1079);
+ static constexpr const TSymbolUniqueId texture_ISampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(1080);
+ static constexpr const TSymbolUniqueId texture_USampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(1081);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(1082);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float3_Float1 =
+ TSymbolUniqueId(1083);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float3_Float1 =
+ TSymbolUniqueId(1084);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(1085);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float4_Float1 =
+ TSymbolUniqueId(1086);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float4_Float1 =
+ TSymbolUniqueId(1087);
+ static constexpr const TSymbolUniqueId textureProj_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(1088);
+ static constexpr const TSymbolUniqueId textureProj_ISampler3D1_Float4_Float1 =
+ TSymbolUniqueId(1089);
+ static constexpr const TSymbolUniqueId textureProj_USampler3D1_Float4_Float1 =
+ TSymbolUniqueId(1090);
+ static constexpr const TSymbolUniqueId texture_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(1091);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeShadow1_Float4_Float1 =
+ TSymbolUniqueId(1092);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(1093);
+ static constexpr const TSymbolUniqueId texture_Sampler1D1_Float1_Float1 = TSymbolUniqueId(1094);
+ static constexpr const TSymbolUniqueId texture_ISampler1D1_Float1_Float1 =
+ TSymbolUniqueId(1095);
+ static constexpr const TSymbolUniqueId texture_USampler1D1_Float1_Float1 =
+ TSymbolUniqueId(1096);
+ static constexpr const TSymbolUniqueId texture_Sampler1DShadow1_Float3_Float1 =
+ TSymbolUniqueId(1097);
+ static constexpr const TSymbolUniqueId texture_Sampler1DArray1_Float3_Float1 =
+ TSymbolUniqueId(1098);
+ static constexpr const TSymbolUniqueId texture_ISampler1DArray1_Float3_Float1 =
+ TSymbolUniqueId(1099);
+ static constexpr const TSymbolUniqueId texture_USampler1DArray1_Float3_Float1 =
+ TSymbolUniqueId(1100);
+ static constexpr const TSymbolUniqueId texture_Sampler1DArrayShadow1_Float3_Float1 =
+ TSymbolUniqueId(1101);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(1102);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1D1_Float2_Float1 =
+ TSymbolUniqueId(1103);
+ static constexpr const TSymbolUniqueId textureProj_ISampler1D1_Float2_Float1 =
+ TSymbolUniqueId(1104);
+ static constexpr const TSymbolUniqueId textureProj_USampler1D1_Float2_Float1 =
+ TSymbolUniqueId(1105);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1D1_Float4_Float1 =
+ TSymbolUniqueId(1106);
+ static constexpr const TSymbolUniqueId textureProj_ISampler1D1_Float4_Float1 =
+ TSymbolUniqueId(1107);
+ static constexpr const TSymbolUniqueId textureProj_USampler1D1_Float4_Float1 =
+ TSymbolUniqueId(1108);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1DShadow1_Float4_Float1 =
+ TSymbolUniqueId(1109);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1110);
+ static constexpr const TSymbolUniqueId texture_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1111);
+ static constexpr const TSymbolUniqueId texture_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1112);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1113);
+ static constexpr const TSymbolUniqueId textureExt_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1114);
+ static constexpr const TSymbolUniqueId textureExt_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1115);
+ static constexpr const TSymbolUniqueId texture_SamplerExternalOES1_Float2_Float1 =
+ TSymbolUniqueId(1116);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float3_Float1 =
+ TSymbolUniqueId(1117);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float4_Float1 =
+ TSymbolUniqueId(1118);
+ static constexpr const TSymbolUniqueId texture_SamplerExternal2DY2YEXT1_Float2_Float1 =
+ TSymbolUniqueId(1119);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float3_Float1 =
+ TSymbolUniqueId(1120);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float4_Float1 =
+ TSymbolUniqueId(1121);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler1D1_Float1 =
+ TSymbolUniqueId(1122);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISampler1D1_Float1 =
+ TSymbolUniqueId(1123);
+ static constexpr const TSymbolUniqueId textureQueryLod_USampler1D1_Float1 =
+ TSymbolUniqueId(1124);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler2D1_Float2 =
+ TSymbolUniqueId(1125);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISampler2D1_Float2 =
+ TSymbolUniqueId(1126);
+ static constexpr const TSymbolUniqueId textureQueryLod_USampler2D1_Float2 =
+ TSymbolUniqueId(1127);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler3D1_Float3 =
+ TSymbolUniqueId(1128);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISampler3D1_Float3 =
+ TSymbolUniqueId(1129);
+ static constexpr const TSymbolUniqueId textureQueryLod_USampler3D1_Float3 =
+ TSymbolUniqueId(1130);
+ static constexpr const TSymbolUniqueId textureQueryLod_SamplerCube1_Float3 =
+ TSymbolUniqueId(1131);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISamplerCube1_Float3 =
+ TSymbolUniqueId(1132);
+ static constexpr const TSymbolUniqueId textureQueryLod_USamplerCube1_Float3 =
+ TSymbolUniqueId(1133);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler1DArray1_Float1 =
+ TSymbolUniqueId(1134);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISampler1DArray1_Float1 =
+ TSymbolUniqueId(1135);
+ static constexpr const TSymbolUniqueId textureQueryLod_USampler1DArray1_Float1 =
+ TSymbolUniqueId(1136);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler2DArray1_Float2 =
+ TSymbolUniqueId(1137);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISampler2DArray1_Float2 =
+ TSymbolUniqueId(1138);
+ static constexpr const TSymbolUniqueId textureQueryLod_USampler2DArray1_Float2 =
+ TSymbolUniqueId(1139);
+ static constexpr const TSymbolUniqueId textureQueryLod_SamplerCubeArray1_Float3 =
+ TSymbolUniqueId(1140);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISamplerCubeArray1_Float3 =
+ TSymbolUniqueId(1141);
+ static constexpr const TSymbolUniqueId textureQueryLod_USamplerCubeArray1_Float3 =
+ TSymbolUniqueId(1142);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler1DShadow1_Float1 =
+ TSymbolUniqueId(1143);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler2DShadow1_Float2 =
+ TSymbolUniqueId(1144);
+ static constexpr const TSymbolUniqueId textureQueryLod_SamplerCubeShadow1_Float3 =
+ TSymbolUniqueId(1145);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler1DArrayShadow1_Float1 =
+ TSymbolUniqueId(1146);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler2DArrayShadow1_Float2 =
+ TSymbolUniqueId(1147);
+ static constexpr const TSymbolUniqueId textureQueryLod_SamplerCubeArrayShadow1_Float3 =
+ TSymbolUniqueId(1148);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1149);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1150);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1151);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler3D1_Float3_Int3 =
+ TSymbolUniqueId(1152);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler3D1_Float3_Int3 =
+ TSymbolUniqueId(1153);
+ static constexpr const TSymbolUniqueId textureOffset_USampler3D1_Float3_Int3 =
+ TSymbolUniqueId(1154);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DShadow1_Float3_Int2 =
+ TSymbolUniqueId(1155);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1156);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1157);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1158);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1D1_Float1_Int1 =
+ TSymbolUniqueId(1159);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler1D1_Float1_Int1 =
+ TSymbolUniqueId(1160);
+ static constexpr const TSymbolUniqueId textureOffset_USampler1D1_Float1_Int1 =
+ TSymbolUniqueId(1161);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1162);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1163);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1164);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DRectShadow1_Float3_Int2 =
+ TSymbolUniqueId(1165);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DShadow1_Float3_Int1 =
+ TSymbolUniqueId(1166);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DArray1_Float2_Int1 =
+ TSymbolUniqueId(1167);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler1DArray1_Float2_Int1 =
+ TSymbolUniqueId(1168);
+ static constexpr const TSymbolUniqueId textureOffset_USampler1DArray1_Float2_Int1 =
+ TSymbolUniqueId(1169);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DArrayShadow1_Float3_Int1 =
+ TSymbolUniqueId(1170);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DArrayShadow1_Float4_Int2 =
+ TSymbolUniqueId(1171);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float3_Int2 =
+ TSymbolUniqueId(1172);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float3_Int2 =
+ TSymbolUniqueId(1173);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float3_Int2 =
+ TSymbolUniqueId(1174);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float4_Int2 =
+ TSymbolUniqueId(1175);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float4_Int2 =
+ TSymbolUniqueId(1176);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float4_Int2 =
+ TSymbolUniqueId(1177);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler3D1_Float4_Int3 =
+ TSymbolUniqueId(1178);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler3D1_Float4_Int3 =
+ TSymbolUniqueId(1179);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler3D1_Float4_Int3 =
+ TSymbolUniqueId(1180);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DShadow1_Float4_Int2 =
+ TSymbolUniqueId(1181);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1D1_Float2_Int1 =
+ TSymbolUniqueId(1182);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler1D1_Float2_Int1 =
+ TSymbolUniqueId(1183);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler1D1_Float2_Int1 =
+ TSymbolUniqueId(1184);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1D1_Float4_Int1 =
+ TSymbolUniqueId(1185);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler1D1_Float4_Int1 =
+ TSymbolUniqueId(1186);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler1D1_Float4_Int1 =
+ TSymbolUniqueId(1187);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DRect1_Float3_Int2 =
+ TSymbolUniqueId(1188);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2DRect1_Float3_Int2 =
+ TSymbolUniqueId(1189);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2DRect1_Float3_Int2 =
+ TSymbolUniqueId(1190);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DRect1_Float4_Int2 =
+ TSymbolUniqueId(1191);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2DRect1_Float4_Int2 =
+ TSymbolUniqueId(1192);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2DRect1_Float4_Int2 =
+ TSymbolUniqueId(1193);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DRectShadow1_Float4_Int2 =
+ TSymbolUniqueId(1194);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1DShadow1_Float4_Int1 =
+ TSymbolUniqueId(1195);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(1196);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(1197);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(1198);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(1199);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(1200);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(1201);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2DShadow1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1202);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1203);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1204);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1205);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler1D1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1206);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler1D1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1207);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler1D1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1208);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler1DShadow1_Float3_Float1_Int1 =
+ TSymbolUniqueId(1209);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler1DArray1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1210);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler1DArray1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1211);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler1DArray1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1212);
+ static constexpr const TSymbolUniqueId
+ textureLodOffset_Sampler1DArrayShadow1_Float3_Float1_Int1 = TSymbolUniqueId(1213);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1214);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1215);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1216);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(1217);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(1218);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(1219);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(1220);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(1221);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(1222);
+ static constexpr const TSymbolUniqueId
+ textureProjLodOffset_Sampler2DShadow1_Float4_Float1_Int2 = TSymbolUniqueId(1223);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler1D1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1224);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler1D1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1225);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler1D1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1226);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler1D1_Float4_Float1_Int1 =
+ TSymbolUniqueId(1227);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler1D1_Float4_Float1_Int1 =
+ TSymbolUniqueId(1228);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler1D1_Float4_Float1_Int1 =
+ TSymbolUniqueId(1229);
+ static constexpr const TSymbolUniqueId
+ textureProjLodOffset_Sampler1DShadow1_Float4_Float1_Int1 = TSymbolUniqueId(1230);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(1231);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(1232);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(1233);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(1234);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(1235);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(1236);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(1237);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(1238);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(1239);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(1240);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(1241);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(1242);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2DRect1_Int2_Int2 =
+ TSymbolUniqueId(1243);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2DRect1_Int2_Int2 =
+ TSymbolUniqueId(1244);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler2DRect1_Int2_Int2 =
+ TSymbolUniqueId(1245);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1246);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1247);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1248);
+ static constexpr const TSymbolUniqueId textureGradOffset_Sampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(1249);
+ static constexpr const TSymbolUniqueId textureGradOffset_ISampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(1250);
+ static constexpr const TSymbolUniqueId textureGradOffset_USampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(1251);
+ static constexpr const TSymbolUniqueId textureGradOffset_Sampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(1252);
+ static constexpr const TSymbolUniqueId textureGradOffset_ISampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(1253);
+ static constexpr const TSymbolUniqueId textureGradOffset_USampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(1254);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DShadow1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1255);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1256);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_ISampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1257);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_USampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1258);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DArrayShadow1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1259);
+ static constexpr const TSymbolUniqueId textureGradOffset_Sampler1D1_Float1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1260);
+ static constexpr const TSymbolUniqueId textureGradOffset_ISampler1D1_Float1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1261);
+ static constexpr const TSymbolUniqueId textureGradOffset_USampler1D1_Float1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1262);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DRect1_Float2_Float2_Float2_Int2 = TSymbolUniqueId(1263);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_ISampler2DRect1_Float2_Float2_Float2_Int2 = TSymbolUniqueId(1264);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_USampler2DRect1_Float2_Float2_Float2_Int2 = TSymbolUniqueId(1265);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DRectShadow1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1266);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler1DShadow1_Float3_Float1_Float1_Int1 = TSymbolUniqueId(1267);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler1DArray1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1268);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_ISampler1DArray1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1269);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_USampler1DArray1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1270);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler1DArrayShadow1_Float3_Float1_Float1_Int1 = TSymbolUniqueId(1271);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1272);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1273);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1274);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1275);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1276);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1277);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(1278);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(1279);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(1280);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2DShadow1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1281);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler1D1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1282);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler1D1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1283);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler1D1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1284);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler1D1_Float4_Float1_Float1_Int1 = TSymbolUniqueId(1285);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler1D1_Float4_Float1_Float1_Int1 = TSymbolUniqueId(1286);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler1D1_Float4_Float1_Float1_Int1 = TSymbolUniqueId(1287);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2DRect1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1288);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2DRect1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1289);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2DRect1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1290);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2DRect1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1291);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2DRect1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1292);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2DRect1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1293);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2DRectShadow1_Float4_Float2_Float2_Int2 =
+ TSymbolUniqueId(1294);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler1DShadow1_Float4_Float1_Float1_Int1 = TSymbolUniqueId(1295);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(1296);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(1297);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(1298);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(1299);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(1300);
+ static constexpr const TSymbolUniqueId textureOffset_USampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(1301);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DShadow1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1302);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1303);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1304);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1305);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1D1_Float1_Int1_Float1 =
+ TSymbolUniqueId(1306);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler1D1_Float1_Int1_Float1 =
+ TSymbolUniqueId(1307);
+ static constexpr const TSymbolUniqueId textureOffset_USampler1D1_Float1_Int1_Float1 =
+ TSymbolUniqueId(1308);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DShadow1_Float3_Int1_Float1 =
+ TSymbolUniqueId(1309);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DArray1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1310);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler1DArray1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1311);
+ static constexpr const TSymbolUniqueId textureOffset_USampler1DArray1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1312);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DArrayShadow1_Float3_Int1_Float1 =
+ TSymbolUniqueId(1313);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1314);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1315);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1316);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(1317);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(1318);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(1319);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(1320);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(1321);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(1322);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DShadow1_Float4_Int2_Float1 =
+ TSymbolUniqueId(1323);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1D1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1324);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler1D1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1325);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler1D1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1326);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1D1_Float4_Int1_Float1 =
+ TSymbolUniqueId(1327);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler1D1_Float4_Int1_Float1 =
+ TSymbolUniqueId(1328);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler1D1_Float4_Int1_Float1 =
+ TSymbolUniqueId(1329);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1DShadow1_Float4_Int1_Float1 =
+ TSymbolUniqueId(1330);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2D1_Float2 = TSymbolUniqueId(1331);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2D1_Float2 = TSymbolUniqueId(1332);
+ static constexpr const TSymbolUniqueId textureGather_USampler2D1_Float2 = TSymbolUniqueId(1333);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2D1_Float2_Int1 =
+ TSymbolUniqueId(1334);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2D1_Float2_Int1 =
+ TSymbolUniqueId(1335);
+ static constexpr const TSymbolUniqueId textureGather_USampler2D1_Float2_Int1 =
+ TSymbolUniqueId(1336);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArray1_Float3 =
+ TSymbolUniqueId(1337);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DArray1_Float3 =
+ TSymbolUniqueId(1338);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DArray1_Float3 =
+ TSymbolUniqueId(1339);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(1340);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(1341);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(1342);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCube1_Float3 =
+ TSymbolUniqueId(1343);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCube1_Float3 =
+ TSymbolUniqueId(1344);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCube1_Float3 =
+ TSymbolUniqueId(1345);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(1346);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(1347);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(1348);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1349);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1350);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1351);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1352);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1353);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1354);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(1355);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1356);
+ static constexpr const TSymbolUniqueId textureGatherExt_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1357);
+ static constexpr const TSymbolUniqueId textureGatherExt_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1358);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1359);
+ static constexpr const TSymbolUniqueId textureGatherExt_ISamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1360);
+ static constexpr const TSymbolUniqueId textureGatherExt_USamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1361);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(1362);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DRect1_Float3 =
+ TSymbolUniqueId(1363);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DRect1_Float3 =
+ TSymbolUniqueId(1364);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DRect1_Float3 =
+ TSymbolUniqueId(1365);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DRect1_Float3_Int1 =
+ TSymbolUniqueId(1366);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DRect1_Float3_Int1 =
+ TSymbolUniqueId(1367);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DRect1_Float3_Int1 =
+ TSymbolUniqueId(1368);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DRectShadow1_Float2_Float1 =
+ TSymbolUniqueId(1369);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DShadow1_Float2 =
+ TSymbolUniqueId(1370);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DShadow1_Float2_Float1 =
+ TSymbolUniqueId(1371);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArrayShadow1_Float3 =
+ TSymbolUniqueId(1372);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArrayShadow1_Float3_Float1 =
+ TSymbolUniqueId(1373);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeShadow1_Float3 =
+ TSymbolUniqueId(1374);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeShadow1_Float3_Float1 =
+ TSymbolUniqueId(1375);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1376);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1377);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1378);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1379);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1380);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1381);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DShadow1_Float2_Float1_Int2 =
+ TSymbolUniqueId(1382);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffset_Sampler2DArrayShadow1_Float3_Float1_Int2 = TSymbolUniqueId(1383);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1384);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1385);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1386);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffset_Sampler2DRectShadow1_Float2_Float1_Int2 = TSymbolUniqueId(1387);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1388);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1389);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1390);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(1391);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(1392);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(1393);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DRect1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1394);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DRect1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1395);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DRect1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1396);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1397);
+ static constexpr const TSymbolUniqueId pt10Dx4 = TSymbolUniqueId(1398);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1399);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1400);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1401);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1402);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1403);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_Sampler2DShadow1_Float2_Float1_4xInt2 = TSymbolUniqueId(1404);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_Sampler2DArrayShadow1_Float3_Float1_4xInt2 = TSymbolUniqueId(1405);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1406);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1407);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1408);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1409);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1410);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1411);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DShadow1_Float2_Float1_4xInt2 = TSymbolUniqueId(1412);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DArrayShadow1_Float3_Float1_4xInt2 = TSymbolUniqueId(1413);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DRect1_Float2_4xInt2 =
+ TSymbolUniqueId(1414);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2DRect1_Float2_4xInt2 =
+ TSymbolUniqueId(1415);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2DRect1_Float2_4xInt2 =
+ TSymbolUniqueId(1416);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_Sampler2DRectShadow1_Float2_Float1_4xInt2 = TSymbolUniqueId(1417);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1418);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1419);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1420);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DArray1_Float3_4xInt2_Int1 =
+ TSymbolUniqueId(1421);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_ISampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(1422);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_USampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(1423);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1424);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1425);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1426);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(1427);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(1428);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(1429);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DRect1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1430);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2DRect1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1431);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2DRect1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1432);
+ static constexpr const TSymbolUniqueId rgb_2_yuv_Float3_YuvCscStandardEXT1 =
+ TSymbolUniqueId(1433);
+ static constexpr const TSymbolUniqueId pt00H = TSymbolUniqueId(1434);
+ static constexpr const TSymbolUniqueId yuv_2_rgb_Float3_YuvCscStandardEXT1 =
+ TSymbolUniqueId(1435);
+ static constexpr const TSymbolUniqueId dFdxExt_Float1 = TSymbolUniqueId(1436);
+ static constexpr const TSymbolUniqueId dFdxExt_Float2 = TSymbolUniqueId(1437);
+ static constexpr const TSymbolUniqueId dFdxExt_Float3 = TSymbolUniqueId(1438);
+ static constexpr const TSymbolUniqueId dFdxExt_Float4 = TSymbolUniqueId(1439);
+ static constexpr const TSymbolUniqueId dFdyExt_Float1 = TSymbolUniqueId(1440);
+ static constexpr const TSymbolUniqueId dFdyExt_Float2 = TSymbolUniqueId(1441);
+ static constexpr const TSymbolUniqueId dFdyExt_Float3 = TSymbolUniqueId(1442);
+ static constexpr const TSymbolUniqueId dFdyExt_Float4 = TSymbolUniqueId(1443);
+ static constexpr const TSymbolUniqueId fwidthExt_Float1 = TSymbolUniqueId(1444);
+ static constexpr const TSymbolUniqueId fwidthExt_Float2 = TSymbolUniqueId(1445);
+ static constexpr const TSymbolUniqueId fwidthExt_Float3 = TSymbolUniqueId(1446);
+ static constexpr const TSymbolUniqueId fwidthExt_Float4 = TSymbolUniqueId(1447);
+ static constexpr const TSymbolUniqueId dFdx_Float1 = TSymbolUniqueId(1448);
+ static constexpr const TSymbolUniqueId dFdx_Float2 = TSymbolUniqueId(1449);
+ static constexpr const TSymbolUniqueId dFdx_Float3 = TSymbolUniqueId(1450);
+ static constexpr const TSymbolUniqueId dFdx_Float4 = TSymbolUniqueId(1451);
+ static constexpr const TSymbolUniqueId dFdy_Float1 = TSymbolUniqueId(1452);
+ static constexpr const TSymbolUniqueId dFdy_Float2 = TSymbolUniqueId(1453);
+ static constexpr const TSymbolUniqueId dFdy_Float3 = TSymbolUniqueId(1454);
+ static constexpr const TSymbolUniqueId dFdy_Float4 = TSymbolUniqueId(1455);
+ static constexpr const TSymbolUniqueId fwidth_Float1 = TSymbolUniqueId(1456);
+ static constexpr const TSymbolUniqueId fwidth_Float2 = TSymbolUniqueId(1457);
+ static constexpr const TSymbolUniqueId fwidth_Float3 = TSymbolUniqueId(1458);
+ static constexpr const TSymbolUniqueId fwidth_Float4 = TSymbolUniqueId(1459);
+ static constexpr const TSymbolUniqueId dFdxFine_Float1 = TSymbolUniqueId(1460);
+ static constexpr const TSymbolUniqueId dFdxFine_Float2 = TSymbolUniqueId(1461);
+ static constexpr const TSymbolUniqueId dFdxFine_Float3 = TSymbolUniqueId(1462);
+ static constexpr const TSymbolUniqueId dFdxFine_Float4 = TSymbolUniqueId(1463);
+ static constexpr const TSymbolUniqueId dFdyFine_Float1 = TSymbolUniqueId(1464);
+ static constexpr const TSymbolUniqueId dFdyFine_Float2 = TSymbolUniqueId(1465);
+ static constexpr const TSymbolUniqueId dFdyFine_Float3 = TSymbolUniqueId(1466);
+ static constexpr const TSymbolUniqueId dFdyFine_Float4 = TSymbolUniqueId(1467);
+ static constexpr const TSymbolUniqueId dFdxCoarse_Float1 = TSymbolUniqueId(1468);
+ static constexpr const TSymbolUniqueId dFdxCoarse_Float2 = TSymbolUniqueId(1469);
+ static constexpr const TSymbolUniqueId dFdxCoarse_Float3 = TSymbolUniqueId(1470);
+ static constexpr const TSymbolUniqueId dFdxCoarse_Float4 = TSymbolUniqueId(1471);
+ static constexpr const TSymbolUniqueId dFdyCoarse_Float1 = TSymbolUniqueId(1472);
+ static constexpr const TSymbolUniqueId dFdyCoarse_Float2 = TSymbolUniqueId(1473);
+ static constexpr const TSymbolUniqueId dFdyCoarse_Float3 = TSymbolUniqueId(1474);
+ static constexpr const TSymbolUniqueId dFdyCoarse_Float4 = TSymbolUniqueId(1475);
+ static constexpr const TSymbolUniqueId fwidthFine_Float1 = TSymbolUniqueId(1476);
+ static constexpr const TSymbolUniqueId fwidthFine_Float2 = TSymbolUniqueId(1477);
+ static constexpr const TSymbolUniqueId fwidthFine_Float3 = TSymbolUniqueId(1478);
+ static constexpr const TSymbolUniqueId fwidthFine_Float4 = TSymbolUniqueId(1479);
+ static constexpr const TSymbolUniqueId fwidthCoarse_Float1 = TSymbolUniqueId(1480);
+ static constexpr const TSymbolUniqueId fwidthCoarse_Float2 = TSymbolUniqueId(1481);
+ static constexpr const TSymbolUniqueId fwidthCoarse_Float3 = TSymbolUniqueId(1482);
+ static constexpr const TSymbolUniqueId fwidthCoarse_Float4 = TSymbolUniqueId(1483);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float1 = TSymbolUniqueId(1484);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float2 = TSymbolUniqueId(1485);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float3 = TSymbolUniqueId(1486);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float4 = TSymbolUniqueId(1487);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float1_Int1 = TSymbolUniqueId(1488);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float2_Int1 = TSymbolUniqueId(1489);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float3_Int1 = TSymbolUniqueId(1490);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float4_Int1 = TSymbolUniqueId(1491);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float1_Float2 =
+ TSymbolUniqueId(1492);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float2_Float2 =
+ TSymbolUniqueId(1493);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float3_Float2 =
+ TSymbolUniqueId(1494);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float4_Float2 =
+ TSymbolUniqueId(1495);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float1 = TSymbolUniqueId(1496);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float2 = TSymbolUniqueId(1497);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float3 = TSymbolUniqueId(1498);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float4 = TSymbolUniqueId(1499);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float1_Int1 =
+ TSymbolUniqueId(1500);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float2_Int1 =
+ TSymbolUniqueId(1501);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float3_Int1 =
+ TSymbolUniqueId(1502);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float4_Int1 =
+ TSymbolUniqueId(1503);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float1_Float2 =
+ TSymbolUniqueId(1504);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float2_Float2 =
+ TSymbolUniqueId(1505);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float3_Float2 =
+ TSymbolUniqueId(1506);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float4_Float2 =
+ TSymbolUniqueId(1507);
+ static constexpr const TSymbolUniqueId atomicCounter_AtomicCounter1 = TSymbolUniqueId(1508);
+ static constexpr const TSymbolUniqueId pt00G = TSymbolUniqueId(1509);
+ static constexpr const TSymbolUniqueId atomicCounterIncrement_AtomicCounter1 =
+ TSymbolUniqueId(1510);
+ static constexpr const TSymbolUniqueId atomicCounterDecrement_AtomicCounter1 =
+ TSymbolUniqueId(1511);
+ static constexpr const TSymbolUniqueId atomicCounterAdd_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1512);
+ static constexpr const TSymbolUniqueId atomicCounterSubtract_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1513);
+ static constexpr const TSymbolUniqueId atomicCounterMin_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1514);
+ static constexpr const TSymbolUniqueId atomicCounterMax_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1515);
+ static constexpr const TSymbolUniqueId atomicCounterAnd_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1516);
+ static constexpr const TSymbolUniqueId atomicCounterOr_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1517);
+ static constexpr const TSymbolUniqueId atomicCounterXor_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1518);
+ static constexpr const TSymbolUniqueId atomicCounterExchange_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1519);
+ static constexpr const TSymbolUniqueId atomicCounterCompSwap_AtomicCounter1_UInt1_UInt1 =
+ TSymbolUniqueId(1520);
+ static constexpr const TSymbolUniqueId atomicAdd_UInt1_UInt1 = TSymbolUniqueId(1521);
+ static constexpr const TSymbolUniqueId pt_io_00E = TSymbolUniqueId(1522);
+ static constexpr const TSymbolUniqueId atomicAdd_Int1_Int1 = TSymbolUniqueId(1523);
+ static constexpr const TSymbolUniqueId pt_io_00D = TSymbolUniqueId(1524);
+ static constexpr const TSymbolUniqueId atomicMin_UInt1_UInt1 = TSymbolUniqueId(1525);
+ static constexpr const TSymbolUniqueId atomicMin_Int1_Int1 = TSymbolUniqueId(1526);
+ static constexpr const TSymbolUniqueId atomicMax_UInt1_UInt1 = TSymbolUniqueId(1527);
+ static constexpr const TSymbolUniqueId atomicMax_Int1_Int1 = TSymbolUniqueId(1528);
+ static constexpr const TSymbolUniqueId atomicAnd_UInt1_UInt1 = TSymbolUniqueId(1529);
+ static constexpr const TSymbolUniqueId atomicAnd_Int1_Int1 = TSymbolUniqueId(1530);
+ static constexpr const TSymbolUniqueId atomicOr_UInt1_UInt1 = TSymbolUniqueId(1531);
+ static constexpr const TSymbolUniqueId atomicOr_Int1_Int1 = TSymbolUniqueId(1532);
+ static constexpr const TSymbolUniqueId atomicXor_UInt1_UInt1 = TSymbolUniqueId(1533);
+ static constexpr const TSymbolUniqueId atomicXor_Int1_Int1 = TSymbolUniqueId(1534);
+ static constexpr const TSymbolUniqueId atomicExchange_UInt1_UInt1 = TSymbolUniqueId(1535);
+ static constexpr const TSymbolUniqueId atomicExchange_Int1_Int1 = TSymbolUniqueId(1536);
+ static constexpr const TSymbolUniqueId atomicCompSwap_UInt1_UInt1_UInt1 = TSymbolUniqueId(1537);
+ static constexpr const TSymbolUniqueId atomicCompSwap_Int1_Int1_Int1 = TSymbolUniqueId(1538);
+ static constexpr const TSymbolUniqueId imageSize_Image2D1 = TSymbolUniqueId(1539);
+ static constexpr const TSymbolUniqueId pt00z = TSymbolUniqueId(1540);
+ static constexpr const TSymbolUniqueId imageSize_IImage2D1 = TSymbolUniqueId(1541);
+ static constexpr const TSymbolUniqueId pt01K = TSymbolUniqueId(1542);
+ static constexpr const TSymbolUniqueId imageSize_UImage2D1 = TSymbolUniqueId(1543);
+ static constexpr const TSymbolUniqueId pt01V = TSymbolUniqueId(1544);
+ static constexpr const TSymbolUniqueId imageSize_Image3D1 = TSymbolUniqueId(1545);
+ static constexpr const TSymbolUniqueId pt01A = TSymbolUniqueId(1546);
+ static constexpr const TSymbolUniqueId imageSize_IImage3D1 = TSymbolUniqueId(1547);
+ static constexpr const TSymbolUniqueId pt01L = TSymbolUniqueId(1548);
+ static constexpr const TSymbolUniqueId imageSize_UImage3D1 = TSymbolUniqueId(1549);
+ static constexpr const TSymbolUniqueId pt01W = TSymbolUniqueId(1550);
+ static constexpr const TSymbolUniqueId imageSize_Image2DArray1 = TSymbolUniqueId(1551);
+ static constexpr const TSymbolUniqueId pt01B = TSymbolUniqueId(1552);
+ static constexpr const TSymbolUniqueId imageSize_IImage2DArray1 = TSymbolUniqueId(1553);
+ static constexpr const TSymbolUniqueId pt01M = TSymbolUniqueId(1554);
+ static constexpr const TSymbolUniqueId imageSize_UImage2DArray1 = TSymbolUniqueId(1555);
+ static constexpr const TSymbolUniqueId pt01X = TSymbolUniqueId(1556);
+ static constexpr const TSymbolUniqueId imageSize_ImageCube1 = TSymbolUniqueId(1557);
+ static constexpr const TSymbolUniqueId pt01C = TSymbolUniqueId(1558);
+ static constexpr const TSymbolUniqueId imageSize_IImageCube1 = TSymbolUniqueId(1559);
+ static constexpr const TSymbolUniqueId pt01N = TSymbolUniqueId(1560);
+ static constexpr const TSymbolUniqueId imageSize_UImageCube1 = TSymbolUniqueId(1561);
+ static constexpr const TSymbolUniqueId pt01Y = TSymbolUniqueId(1562);
+ static constexpr const TSymbolUniqueId imageSize_ImageCubeArray1 = TSymbolUniqueId(1563);
+ static constexpr const TSymbolUniqueId pt01H = TSymbolUniqueId(1564);
+ static constexpr const TSymbolUniqueId imageSize_IImageCubeArray1 = TSymbolUniqueId(1565);
+ static constexpr const TSymbolUniqueId pt01S = TSymbolUniqueId(1566);
+ static constexpr const TSymbolUniqueId imageSize_UImageCubeArray1 = TSymbolUniqueId(1567);
+ static constexpr const TSymbolUniqueId pt01d = TSymbolUniqueId(1568);
+ static constexpr const TSymbolUniqueId imageSizeExt_ImageCubeArray1 = TSymbolUniqueId(1569);
+ static constexpr const TSymbolUniqueId imageSizeExt_IImageCubeArray1 = TSymbolUniqueId(1570);
+ static constexpr const TSymbolUniqueId imageSizeExt_UImageCubeArray1 = TSymbolUniqueId(1571);
+ static constexpr const TSymbolUniqueId imageSize_ImageBuffer1 = TSymbolUniqueId(1572);
+ static constexpr const TSymbolUniqueId pt01J = TSymbolUniqueId(1573);
+ static constexpr const TSymbolUniqueId imageSize_IImageBuffer1 = TSymbolUniqueId(1574);
+ static constexpr const TSymbolUniqueId pt01U = TSymbolUniqueId(1575);
+ static constexpr const TSymbolUniqueId imageSize_UImageBuffer1 = TSymbolUniqueId(1576);
+ static constexpr const TSymbolUniqueId pt01f = TSymbolUniqueId(1577);
+ static constexpr const TSymbolUniqueId imageSizeExt_ImageBuffer1 = TSymbolUniqueId(1578);
+ static constexpr const TSymbolUniqueId imageSizeExt_IImageBuffer1 = TSymbolUniqueId(1579);
+ static constexpr const TSymbolUniqueId imageSizeExt_UImageBuffer1 = TSymbolUniqueId(1580);
+ static constexpr const TSymbolUniqueId imageSize_Image1D1 = TSymbolUniqueId(1581);
+ static constexpr const TSymbolUniqueId pt01D = TSymbolUniqueId(1582);
+ static constexpr const TSymbolUniqueId imageSize_IImage1D1 = TSymbolUniqueId(1583);
+ static constexpr const TSymbolUniqueId pt01O = TSymbolUniqueId(1584);
+ static constexpr const TSymbolUniqueId imageSize_UImage1D1 = TSymbolUniqueId(1585);
+ static constexpr const TSymbolUniqueId pt01Z = TSymbolUniqueId(1586);
+ static constexpr const TSymbolUniqueId imageSize_ImageRect1 = TSymbolUniqueId(1587);
+ static constexpr const TSymbolUniqueId pt01I = TSymbolUniqueId(1588);
+ static constexpr const TSymbolUniqueId imageSize_IImageRect1 = TSymbolUniqueId(1589);
+ static constexpr const TSymbolUniqueId pt01T = TSymbolUniqueId(1590);
+ static constexpr const TSymbolUniqueId imageSize_UImageRect1 = TSymbolUniqueId(1591);
+ static constexpr const TSymbolUniqueId pt01e = TSymbolUniqueId(1592);
+ static constexpr const TSymbolUniqueId imageSize_Image1DArray1 = TSymbolUniqueId(1593);
+ static constexpr const TSymbolUniqueId pt01E = TSymbolUniqueId(1594);
+ static constexpr const TSymbolUniqueId imageSize_IImage1DArray1 = TSymbolUniqueId(1595);
+ static constexpr const TSymbolUniqueId pt01P = TSymbolUniqueId(1596);
+ static constexpr const TSymbolUniqueId imageSize_UImage1DArray1 = TSymbolUniqueId(1597);
+ static constexpr const TSymbolUniqueId pt01a = TSymbolUniqueId(1598);
+ static constexpr const TSymbolUniqueId imageSize_Image2DMS1 = TSymbolUniqueId(1599);
+ static constexpr const TSymbolUniqueId pt01F = TSymbolUniqueId(1600);
+ static constexpr const TSymbolUniqueId imageSize_IImage2DMS1 = TSymbolUniqueId(1601);
+ static constexpr const TSymbolUniqueId pt01Q = TSymbolUniqueId(1602);
+ static constexpr const TSymbolUniqueId imageSize_UImage2DMS1 = TSymbolUniqueId(1603);
+ static constexpr const TSymbolUniqueId pt01b = TSymbolUniqueId(1604);
+ static constexpr const TSymbolUniqueId imageSize_Image2DMSArray1 = TSymbolUniqueId(1605);
+ static constexpr const TSymbolUniqueId pt01G = TSymbolUniqueId(1606);
+ static constexpr const TSymbolUniqueId imageSize_IImage2DMSArray1 = TSymbolUniqueId(1607);
+ static constexpr const TSymbolUniqueId pt01R = TSymbolUniqueId(1608);
+ static constexpr const TSymbolUniqueId imageSize_UImage2DMSArray1 = TSymbolUniqueId(1609);
+ static constexpr const TSymbolUniqueId pt01c = TSymbolUniqueId(1610);
+ static constexpr const TSymbolUniqueId imageSamples_Image2DMS1 = TSymbolUniqueId(1611);
+ static constexpr const TSymbolUniqueId imageSamples_IImage2DMS1 = TSymbolUniqueId(1612);
+ static constexpr const TSymbolUniqueId imageSamples_UImage2DMS1 = TSymbolUniqueId(1613);
+ static constexpr const TSymbolUniqueId imageSamples_Image2DMSArray1 = TSymbolUniqueId(1614);
+ static constexpr const TSymbolUniqueId imageSamples_IImage2DMSArray1 = TSymbolUniqueId(1615);
+ static constexpr const TSymbolUniqueId imageSamples_UImage2DMSArray1 = TSymbolUniqueId(1616);
+ static constexpr const TSymbolUniqueId imageStore_Image2D1_Int2_Float4 = TSymbolUniqueId(1617);
+ static constexpr const TSymbolUniqueId imageStore_IImage2D1_Int2_Int4 = TSymbolUniqueId(1618);
+ static constexpr const TSymbolUniqueId imageStore_UImage2D1_Int2_UInt4 = TSymbolUniqueId(1619);
+ static constexpr const TSymbolUniqueId imageStore_Image3D1_Int3_Float4 = TSymbolUniqueId(1620);
+ static constexpr const TSymbolUniqueId imageStore_IImage3D1_Int3_Int4 = TSymbolUniqueId(1621);
+ static constexpr const TSymbolUniqueId imageStore_UImage3D1_Int3_UInt4 = TSymbolUniqueId(1622);
+ static constexpr const TSymbolUniqueId imageStore_Image2DArray1_Int3_Float4 =
+ TSymbolUniqueId(1623);
+ static constexpr const TSymbolUniqueId imageStore_IImage2DArray1_Int3_Int4 =
+ TSymbolUniqueId(1624);
+ static constexpr const TSymbolUniqueId imageStore_UImage2DArray1_Int3_UInt4 =
+ TSymbolUniqueId(1625);
+ static constexpr const TSymbolUniqueId imageStore_ImageCube1_Int3_Float4 =
+ TSymbolUniqueId(1626);
+ static constexpr const TSymbolUniqueId imageStore_IImageCube1_Int3_Int4 = TSymbolUniqueId(1627);
+ static constexpr const TSymbolUniqueId imageStore_UImageCube1_Int3_UInt4 =
+ TSymbolUniqueId(1628);
+ static constexpr const TSymbolUniqueId imageStore_ImageCubeArray1_Int3_Float4 =
+ TSymbolUniqueId(1629);
+ static constexpr const TSymbolUniqueId imageStore_IImageCubeArray1_Int3_Int4 =
+ TSymbolUniqueId(1630);
+ static constexpr const TSymbolUniqueId imageStore_UImageCubeArray1_Int3_UInt4 =
+ TSymbolUniqueId(1631);
+ static constexpr const TSymbolUniqueId imageStoreExt_ImageCubeArray1_Int3_Float4 =
+ TSymbolUniqueId(1632);
+ static constexpr const TSymbolUniqueId imageStoreExt_IImageCubeArray1_Int3_Int4 =
+ TSymbolUniqueId(1633);
+ static constexpr const TSymbolUniqueId imageStoreExt_UImageCubeArray1_Int3_UInt4 =
+ TSymbolUniqueId(1634);
+ static constexpr const TSymbolUniqueId imageStore_ImageBuffer1_Int1_Float4 =
+ TSymbolUniqueId(1635);
+ static constexpr const TSymbolUniqueId imageStore_IImageBuffer1_Int1_Int4 =
+ TSymbolUniqueId(1636);
+ static constexpr const TSymbolUniqueId imageStore_UImageBuffer1_Int1_UInt4 =
+ TSymbolUniqueId(1637);
+ static constexpr const TSymbolUniqueId imageStoreExt_ImageBuffer1_Int1_Float4 =
+ TSymbolUniqueId(1638);
+ static constexpr const TSymbolUniqueId imageStoreExt_IImageBuffer1_Int1_Int4 =
+ TSymbolUniqueId(1639);
+ static constexpr const TSymbolUniqueId imageStoreExt_UImageBuffer1_Int1_UInt4 =
+ TSymbolUniqueId(1640);
+ static constexpr const TSymbolUniqueId imageStore_Image1D1_Int1_Float4 = TSymbolUniqueId(1641);
+ static constexpr const TSymbolUniqueId imageStore_IImage1D1_Int1_Int4 = TSymbolUniqueId(1642);
+ static constexpr const TSymbolUniqueId imageStore_UImage1D1_Int1_UInt4 = TSymbolUniqueId(1643);
+ static constexpr const TSymbolUniqueId imageStore_Image1DArray1_Int2_Float4 =
+ TSymbolUniqueId(1644);
+ static constexpr const TSymbolUniqueId imageStore_IImage1DArray1_Int2_Int4 =
+ TSymbolUniqueId(1645);
+ static constexpr const TSymbolUniqueId imageStore_UImage1DArray1_Int2_UInt4 =
+ TSymbolUniqueId(1646);
+ static constexpr const TSymbolUniqueId imageStore_ImageRect1_Int2_Float4 =
+ TSymbolUniqueId(1647);
+ static constexpr const TSymbolUniqueId imageStore_IImageRect1_Int2_Int4 = TSymbolUniqueId(1648);
+ static constexpr const TSymbolUniqueId imageStore_UImageRect1_Int2_UInt4 =
+ TSymbolUniqueId(1649);
+ static constexpr const TSymbolUniqueId imageStore_Image2DMS1_Int2_Int1_Float4 =
+ TSymbolUniqueId(1650);
+ static constexpr const TSymbolUniqueId imageStore_IImage2DMS1_Int2_Int1_Int4 =
+ TSymbolUniqueId(1651);
+ static constexpr const TSymbolUniqueId imageStore_UImage2DMS1_Int2_Int1_UInt4 =
+ TSymbolUniqueId(1652);
+ static constexpr const TSymbolUniqueId imageStore_Image2DMSArray1_Int3_Int1_Float4 =
+ TSymbolUniqueId(1653);
+ static constexpr const TSymbolUniqueId imageStore_IImage2DMSArray1_Int3_Int1_Int4 =
+ TSymbolUniqueId(1654);
+ static constexpr const TSymbolUniqueId imageStore_UImage2DMSArray1_Int3_Int1_UInt4 =
+ TSymbolUniqueId(1655);
+ static constexpr const TSymbolUniqueId imageLoad_Image2D1_Int2 = TSymbolUniqueId(1656);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2D1_Int2 = TSymbolUniqueId(1657);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2D1_Int2 = TSymbolUniqueId(1658);
+ static constexpr const TSymbolUniqueId imageLoad_Image3D1_Int3 = TSymbolUniqueId(1659);
+ static constexpr const TSymbolUniqueId imageLoad_IImage3D1_Int3 = TSymbolUniqueId(1660);
+ static constexpr const TSymbolUniqueId imageLoad_UImage3D1_Int3 = TSymbolUniqueId(1661);
+ static constexpr const TSymbolUniqueId imageLoad_Image2DArray1_Int3 = TSymbolUniqueId(1662);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2DArray1_Int3 = TSymbolUniqueId(1663);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2DArray1_Int3 = TSymbolUniqueId(1664);
+ static constexpr const TSymbolUniqueId imageLoad_ImageCube1_Int3 = TSymbolUniqueId(1665);
+ static constexpr const TSymbolUniqueId imageLoad_IImageCube1_Int3 = TSymbolUniqueId(1666);
+ static constexpr const TSymbolUniqueId imageLoad_UImageCube1_Int3 = TSymbolUniqueId(1667);
+ static constexpr const TSymbolUniqueId imageLoad_ImageCubeArray1_Int3 = TSymbolUniqueId(1668);
+ static constexpr const TSymbolUniqueId imageLoad_IImageCubeArray1_Int3 = TSymbolUniqueId(1669);
+ static constexpr const TSymbolUniqueId imageLoad_UImageCubeArray1_Int3 = TSymbolUniqueId(1670);
+ static constexpr const TSymbolUniqueId imageLoadExt_ImageCubeArray1_Int3 =
+ TSymbolUniqueId(1671);
+ static constexpr const TSymbolUniqueId imageLoadExt_IImageCubeArray1_Int3 =
+ TSymbolUniqueId(1672);
+ static constexpr const TSymbolUniqueId imageLoadExt_UImageCubeArray1_Int3 =
+ TSymbolUniqueId(1673);
+ static constexpr const TSymbolUniqueId imageLoad_ImageBuffer1_Int1 = TSymbolUniqueId(1674);
+ static constexpr const TSymbolUniqueId imageLoad_IImageBuffer1_Int1 = TSymbolUniqueId(1675);
+ static constexpr const TSymbolUniqueId imageLoad_UImageBuffer1_Int1 = TSymbolUniqueId(1676);
+ static constexpr const TSymbolUniqueId imageLoadExt_ImageBuffer1_Int1 = TSymbolUniqueId(1677);
+ static constexpr const TSymbolUniqueId imageLoadExt_IImageBuffer1_Int1 = TSymbolUniqueId(1678);
+ static constexpr const TSymbolUniqueId imageLoadExt_UImageBuffer1_Int1 = TSymbolUniqueId(1679);
+ static constexpr const TSymbolUniqueId imageLoad_Image1D1_Int1 = TSymbolUniqueId(1680);
+ static constexpr const TSymbolUniqueId imageLoad_IImage1D1_Int1 = TSymbolUniqueId(1681);
+ static constexpr const TSymbolUniqueId imageLoad_UImage1D1_Int1 = TSymbolUniqueId(1682);
+ static constexpr const TSymbolUniqueId imageLoad_Image1DArray1_Int2 = TSymbolUniqueId(1683);
+ static constexpr const TSymbolUniqueId imageLoad_IImage1DArray1_Int2 = TSymbolUniqueId(1684);
+ static constexpr const TSymbolUniqueId imageLoad_UImage1DArray1_Int2 = TSymbolUniqueId(1685);
+ static constexpr const TSymbolUniqueId imageLoad_ImageRect1_Int2 = TSymbolUniqueId(1686);
+ static constexpr const TSymbolUniqueId imageLoad_IImageRect1_Int2 = TSymbolUniqueId(1687);
+ static constexpr const TSymbolUniqueId imageLoad_UImageRect1_Int2 = TSymbolUniqueId(1688);
+ static constexpr const TSymbolUniqueId imageLoad_Image2DMS1_Int2_Int1 = TSymbolUniqueId(1689);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2DMS1_Int2_Int1 = TSymbolUniqueId(1690);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2DMS1_Int2_Int1 = TSymbolUniqueId(1691);
+ static constexpr const TSymbolUniqueId imageLoad_Image2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(1692);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(1693);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(1694);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(1695);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1696);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1697);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(1698);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1699);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1700);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1701);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1702);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1703);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1704);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1705);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1706);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1707);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1708);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1709);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1710);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1711);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1712);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(1713);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1714);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1715);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1716);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1717);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1718);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1719);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1720);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1721);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1722);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1723);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1724);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1725);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1726);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1727);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(1728);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1729);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1730);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(1731);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1732);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1733);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1734);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1735);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1736);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1737);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1738);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1739);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1740);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1741);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1742);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1743);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1744);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1745);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(1746);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1747);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1748);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1749);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1750);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1751);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1752);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1753);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1754);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1755);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1756);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1757);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1758);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1759);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1760);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(1761);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1762);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1763);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(1764);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1765);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1766);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1767);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1768);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1769);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1770);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1771);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1772);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1773);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1774);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1775);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1776);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1777);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1778);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(1779);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1780);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1781);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1782);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1783);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1784);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1785);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1786);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1787);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1788);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1789);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1790);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1791);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1792);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1793);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(1794);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1795);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1796);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(1797);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1798);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1799);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1800);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1801);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1802);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1803);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1804);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1805);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1806);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1807);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1808);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1809);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1810);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1811);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(1812);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1813);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1814);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1815);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1816);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1817);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1818);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1819);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1820);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1821);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1822);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1823);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1824);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1825);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1826);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(1827);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1828);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1829);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(1830);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1831);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1832);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1833);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1834);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1835);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1836);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1837);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1838);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1839);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1840);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1841);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1842);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1843);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1844);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(1845);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1846);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1847);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1848);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1849);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1850);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1851);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1852);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1853);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1854);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1855);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1856);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1857);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1858);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1859);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(1860);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1861);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1862);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(1863);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1864);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1865);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1866);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1867);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1868);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1869);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1870);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1871);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1872);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1873);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1874);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1875);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1876);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1877);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(1878);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1879);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1880);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1881);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1882);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1883);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1884);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1885);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1886);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1887);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1888);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1889);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1890);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1891);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1892);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(1893);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1894);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1895);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(1896);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1897);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1898);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1899);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1900);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1901);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1902);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1903);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1904);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1905);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1906);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1907);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1908);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1909);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1910);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(1911);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1912);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1913);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1914);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1915);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1916);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1917);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1918);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1919);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1920);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1921);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1922);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1923);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1924);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1925);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(1926);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1927);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1928);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(1929);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1930);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1931);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1932);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1933);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1934);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1935);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1936);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1937);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1938);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1939);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1940);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1941);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1942);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1943);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(1944);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1945);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1946);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1947);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1948);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1949);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1950);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1951);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1952);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1953);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1954);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1955);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1956);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1957);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1958);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(1959);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1960);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1961);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(1962);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1963);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1964);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1965);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1966);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1967);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1968);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1969);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1970);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1971);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1972);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1973);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1974);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1975);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1976);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(1977);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1978);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1979);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1980);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1981);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1982);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1983);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1984);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1985);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1986);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1987);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1988);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1989);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1990);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1991);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2D1_Int2_Int1 = TSymbolUniqueId(1992);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1993);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1994);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image3D1_Int3_Int1 = TSymbolUniqueId(1995);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1996);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1997);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1998);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1999);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2000);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2001);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2002);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2003);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2004);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2005);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2006);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2007);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2008);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2009);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1D1_Int1_Int1 = TSymbolUniqueId(2010);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2011);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2012);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2013);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2014);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2015);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2016);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2017);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2018);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2019);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2020);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2021);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2022);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2023);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2024);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2025);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2026);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2027);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2028);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2029);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2030);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2031);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2032);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2033);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2034);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2035);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2036);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2037);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2038);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2039);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2040);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2041);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2042);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2043);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2044);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2045);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2046);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2047);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2048);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2049);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2050);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2051);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2052);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2053);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2054);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2055);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2056);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2057);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2058);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2059);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2060);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2061);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2062);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2063);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2064);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2065);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2066);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2067);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2068);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2069);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2070);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2071);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2072);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2073);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2074);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2075);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2076);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2077);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2078);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2079);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2080);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2081);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2082);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2083);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2084);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2085);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2086);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2087);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2088);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2089);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2090);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2091);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2092);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2093);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2094);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2095);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2096);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2097);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2098);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2099);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2100);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2101);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2102);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2103);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2104);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2105);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2106);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2107);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2108);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2109);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2110);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2111);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2112);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2113);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2114);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2115);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2116);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2117);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2118);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2119);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2120);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2121);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2122);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2123);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2124);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2125);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2126);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2127);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2128);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2129);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2130);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2131);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2132);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2133);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2134);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2135);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2136);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2137);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2138);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2139);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2140);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2141);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2142);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2143);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2144);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2145);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2146);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2147);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2148);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2149);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2150);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2151);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2152);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2153);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2154);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2155);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2156);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_Float1 =
+ TSymbolUniqueId(2157);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_Float1 =
+ TSymbolUniqueId(2158);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_Float1 =
+ TSymbolUniqueId(2159);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_Float1 =
+ TSymbolUniqueId(2160);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_Float1 =
+ TSymbolUniqueId(2161);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_Float1 =
+ TSymbolUniqueId(2162);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2163);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2164);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2165);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2166);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2167);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2168);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2169);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2170);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2171);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2172);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2173);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2174);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_Float1 =
+ TSymbolUniqueId(2175);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_Float1 =
+ TSymbolUniqueId(2176);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_Float1 =
+ TSymbolUniqueId(2177);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2178);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2179);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2180);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2181);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2182);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2183);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2184);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2185);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2186);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(2187);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(2188);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(2189);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2190);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2191);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2192);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2193);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2194);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2195);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2196);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2197);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2198);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2199);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2200);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2201);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2202);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2203);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2204);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2205);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2206);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2207);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2208);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2209);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2210);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2211);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2212);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2213);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2214);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2215);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2216);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2217);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2218);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2219);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2220);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2221);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2222);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2223);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2224);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2225);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2226);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2227);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2228);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2229);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2230);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2231);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2232);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2233);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2234);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2235);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2236);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2237);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2238);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2239);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2240);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2241);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2242);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2243);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2244);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2245);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2246);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2247);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2248);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2249);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2250);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2251);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2252);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_Int1_Int1 =
+ TSymbolUniqueId(2253);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(2254);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(2255);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2256);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2257);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2258);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2259);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2260);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2261);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2262);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2263);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2264);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2265);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2266);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2267);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2268);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2269);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2270);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2271);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2272);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2273);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2274);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2275);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2276);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2277);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2278);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2279);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2280);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2281);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2282);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2283);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2284);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2285);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2286);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2287);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2288);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2289);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2290);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2291);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2292);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2293);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2294);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2295);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2296);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2297);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2298);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2299);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2300);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2301);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2302);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2303);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2304);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2305);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2306);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2307);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2308);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2309);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2310);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2311);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2312);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2313);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2314);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2315);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2316);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2317);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2318);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2319);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2320);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2321);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2322);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2323);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2324);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2325);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2326);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2327);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2328);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2329);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2330);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2331);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2332);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2333);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2334);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2335);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2336);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2337);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2338);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2339);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2340);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2341);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2342);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2343);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2344);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2345);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2346);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2347);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2348);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2349);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2350);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2351);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2352);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2353);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2354);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2355);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2356);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2357);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2358);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2359);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2360);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2361);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2362);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2363);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2364);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2365);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2366);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2367);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2368);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2369);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2370);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2371);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2372);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2373);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2374);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2375);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2376);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2377);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2378);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2379);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2380);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2381);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2382);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2383);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2384);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2385);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2386);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2387);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2388);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2389);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2390);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2391);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2392);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2393);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2394);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2395);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2396);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2397);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2398);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2399);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2400);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2401);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2402);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2403);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2404);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2405);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2406);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2407);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2408);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2409);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2410);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2411);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2412);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2413);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2414);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2415);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2416);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2417);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2418);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2419);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2420);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2421);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2422);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2423);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2424);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2425);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2426);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2427);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2428);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2429);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2430);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2431);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2432);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2433);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2434);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2435);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2436);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2437);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2438);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2439);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2440);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2441);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2442);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2443);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2444);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2445);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2446);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2447);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2448);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2449);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2450);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2451);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2452);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2453);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2454);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2455);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2456);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2457);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2458);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2459);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2460);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2461);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2462);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2463);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2464);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2465);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2466);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2467);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2468);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2469);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2470);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2471);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2472);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2473);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2474);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2475);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2476);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2477);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2478);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2479);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2480);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2481);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2482);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2483);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2484);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2485);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2486);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2487);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2488);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2489);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2490);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2491);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2492);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2493);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2494);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2495);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2496);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2497);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2498);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2499);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2500);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2501);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2502);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2503);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2504);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2505);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2506);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2507);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2508);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2509);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2510);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2511);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2512);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2513);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2514);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2515);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2516);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2517);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2518);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2519);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2520);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2521);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2522);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2523);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2524);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2525);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2526);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2527);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2528);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2529);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2530);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2531);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2532);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2533);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2534);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2535);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2536);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2537);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2538);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2539);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2540);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2541);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2542);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2543);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2544);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2545);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2546);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2547);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2548);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2549);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2550);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2551);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2552);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2553);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2554);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2555);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2556);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2557);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2558);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2559);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2560);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2561);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2562);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2563);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2564);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2565);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2566);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2567);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2568);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2569);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2570);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2571);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2572);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2573);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2574);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2575);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2576);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2577);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2578);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2579);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2580);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2581);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2582);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2583);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2584);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2585);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2586);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2587);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2588);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2589);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2590);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2591);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2592);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2593);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2594);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2595);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2596);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2597);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2598);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2599);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2600);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2601);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2602);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2603);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2604);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2605);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2606);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2607);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2608);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2609);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2610);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2611);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2612);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2613);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2614);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2615);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2616);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2617);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2618);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2619);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2620);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2621);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2622);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2623);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2624);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2625);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2626);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2627);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2628);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2629);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2630);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2631);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2632);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2633);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2634);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2635);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2636);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2637);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2638);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2639);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2640);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2641);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2642);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2643);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2644);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2645);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2646);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2647);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2648);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2649);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2650);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2651);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2652);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2653);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2654);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2655);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2656);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2657);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2658);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2659);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2660);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2661);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2662);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2663);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2664);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2665);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2666);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2667);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2668);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2669);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2670);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2671);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2672);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2673);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2674);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2675);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2676);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2677);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2678);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2679);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2680);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2681);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2682);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2683);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2684);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2685);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2686);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2687);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2688);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2689);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2690);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2691);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2692);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2693);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2694);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2695);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2696);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2697);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2698);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2699);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2700);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2701);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2702);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2703);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2704);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2705);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2706);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2707);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2708);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2709);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2710);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2711);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2712);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2713);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2714);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2715);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2716);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2717);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_Float1 =
+ TSymbolUniqueId(2718);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_Float1 =
+ TSymbolUniqueId(2719);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_Float1 =
+ TSymbolUniqueId(2720);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_Float1 =
+ TSymbolUniqueId(2721);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_Float1 =
+ TSymbolUniqueId(2722);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_Float1 =
+ TSymbolUniqueId(2723);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2724);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2725);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2726);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2727);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2728);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2729);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2730);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2731);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2732);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2733);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2734);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2735);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_Float1 =
+ TSymbolUniqueId(2736);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_Float1 =
+ TSymbolUniqueId(2737);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_Float1 =
+ TSymbolUniqueId(2738);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2739);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2740);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2741);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2742);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2743);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2744);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2745);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2746);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2747);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(2748);
+ static constexpr const TSymbolUniqueId
+ imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Float1 = TSymbolUniqueId(2749);
+ static constexpr const TSymbolUniqueId
+ imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Float1 = TSymbolUniqueId(2750);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2751);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2752);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2753);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2754);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2755);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2756);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2757);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2758);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2759);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2760);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2761);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2762);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2763);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2764);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2765);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2766);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImageCubeArray1_Int3_UInt1_UInt1 = TSymbolUniqueId(2767);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImageCubeArray1_Int3_UInt1_UInt1 = TSymbolUniqueId(2768);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2769);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2770);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2771);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2772);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2773);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2774);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2775);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2776);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2777);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2778);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_UInt1_UInt1 = TSymbolUniqueId(2779);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_UInt1_UInt1 = TSymbolUniqueId(2780);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2781);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2782);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2783);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2784);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2785);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2786);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2787);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2788);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2789);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2790);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2791);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2792);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2793);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2794);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2795);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2796);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2797);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2798);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2799);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2800);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2801);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2802);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2803);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2804);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2805);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2806);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2807);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2808);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2809);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2810);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2811);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2812);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2813);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(2814);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(2815);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(2816);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_PixelLocalANGLE1 =
+ TSymbolUniqueId(2817);
+ static constexpr const TSymbolUniqueId pt01g = TSymbolUniqueId(2818);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_IPixelLocalANGLE1 =
+ TSymbolUniqueId(2819);
+ static constexpr const TSymbolUniqueId pt01h = TSymbolUniqueId(2820);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_UPixelLocalANGLE1 =
+ TSymbolUniqueId(2821);
+ static constexpr const TSymbolUniqueId pt01i = TSymbolUniqueId(2822);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_PixelLocalANGLE1_Float4 =
+ TSymbolUniqueId(2823);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_IPixelLocalANGLE1_Int4 =
+ TSymbolUniqueId(2824);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_UPixelLocalANGLE1_UInt4 =
+ TSymbolUniqueId(2825);
+ static constexpr const TSymbolUniqueId beginInvocationInterlockNV = TSymbolUniqueId(2826);
+ static constexpr const TSymbolUniqueId endInvocationInterlockNV = TSymbolUniqueId(2827);
+ static constexpr const TSymbolUniqueId beginFragmentShaderOrderingINTEL = TSymbolUniqueId(2828);
+ static constexpr const TSymbolUniqueId beginInvocationInterlockARB = TSymbolUniqueId(2829);
+ static constexpr const TSymbolUniqueId endInvocationInterlockARB = TSymbolUniqueId(2830);
+ static constexpr const TSymbolUniqueId noise1_Float1 = TSymbolUniqueId(2831);
+ static constexpr const TSymbolUniqueId noise1_Float2 = TSymbolUniqueId(2832);
+ static constexpr const TSymbolUniqueId noise1_Float3 = TSymbolUniqueId(2833);
+ static constexpr const TSymbolUniqueId noise1_Float4 = TSymbolUniqueId(2834);
+ static constexpr const TSymbolUniqueId noise2_Float1 = TSymbolUniqueId(2835);
+ static constexpr const TSymbolUniqueId noise2_Float2 = TSymbolUniqueId(2836);
+ static constexpr const TSymbolUniqueId noise2_Float3 = TSymbolUniqueId(2837);
+ static constexpr const TSymbolUniqueId noise2_Float4 = TSymbolUniqueId(2838);
+ static constexpr const TSymbolUniqueId noise3_Float1 = TSymbolUniqueId(2839);
+ static constexpr const TSymbolUniqueId noise3_Float2 = TSymbolUniqueId(2840);
+ static constexpr const TSymbolUniqueId noise3_Float3 = TSymbolUniqueId(2841);
+ static constexpr const TSymbolUniqueId noise3_Float4 = TSymbolUniqueId(2842);
+ static constexpr const TSymbolUniqueId noise4_Float1 = TSymbolUniqueId(2843);
+ static constexpr const TSymbolUniqueId noise4_Float2 = TSymbolUniqueId(2844);
+ static constexpr const TSymbolUniqueId noise4_Float3 = TSymbolUniqueId(2845);
+ static constexpr const TSymbolUniqueId noise4_Float4 = TSymbolUniqueId(2846);
+ static constexpr const TSymbolUniqueId memoryBarrier = TSymbolUniqueId(2847);
+ static constexpr const TSymbolUniqueId memoryBarrierAtomicCounter = TSymbolUniqueId(2848);
+ static constexpr const TSymbolUniqueId memoryBarrierBuffer = TSymbolUniqueId(2849);
+ static constexpr const TSymbolUniqueId memoryBarrierImage = TSymbolUniqueId(2850);
+ static constexpr const TSymbolUniqueId barrier = TSymbolUniqueId(2851);
+ static constexpr const TSymbolUniqueId memoryBarrierShared = TSymbolUniqueId(2852);
+ static constexpr const TSymbolUniqueId groupMemoryBarrier = TSymbolUniqueId(2853);
+ static constexpr const TSymbolUniqueId barrierTCS = TSymbolUniqueId(2854);
+ static constexpr const TSymbolUniqueId barrierTCSES3_2 = TSymbolUniqueId(2855);
+ static constexpr const TSymbolUniqueId EmitVertex = TSymbolUniqueId(2856);
+ static constexpr const TSymbolUniqueId EmitVertexES3_2 = TSymbolUniqueId(2857);
+ static constexpr const TSymbolUniqueId EndPrimitive = TSymbolUniqueId(2858);
+ static constexpr const TSymbolUniqueId EndPrimitiveES3_2 = TSymbolUniqueId(2859);
+ static constexpr const TSymbolUniqueId EmitStreamVertex_Int1 = TSymbolUniqueId(2860);
+ static constexpr const TSymbolUniqueId EndStreamPrimitive_Int1 = TSymbolUniqueId(2861);
+ static constexpr const TSymbolUniqueId subpassLoad_SubpassInput1 = TSymbolUniqueId(2862);
+ static constexpr const TSymbolUniqueId pt01j = TSymbolUniqueId(2863);
+ static constexpr const TSymbolUniqueId subpassLoad_ISubpassInput1 = TSymbolUniqueId(2864);
+ static constexpr const TSymbolUniqueId pt01k = TSymbolUniqueId(2865);
+ static constexpr const TSymbolUniqueId subpassLoad_USubpassInput1 = TSymbolUniqueId(2866);
+ static constexpr const TSymbolUniqueId pt01l = TSymbolUniqueId(2867);
+ static constexpr const TSymbolUniqueId subpassLoad_SubpassInputMS1_Int1 = TSymbolUniqueId(2868);
+ static constexpr const TSymbolUniqueId pt01m = TSymbolUniqueId(2869);
+ static constexpr const TSymbolUniqueId subpassLoad_ISubpassInputMS1_Int1 =
+ TSymbolUniqueId(2870);
+ static constexpr const TSymbolUniqueId pt01n = TSymbolUniqueId(2871);
+ static constexpr const TSymbolUniqueId subpassLoad_USubpassInputMS1_Int1 =
+ TSymbolUniqueId(2872);
+ static constexpr const TSymbolUniqueId pt01o = TSymbolUniqueId(2873);
+ static constexpr const TSymbolUniqueId anyInvocation_Bool1 = TSymbolUniqueId(2874);
+ static constexpr const TSymbolUniqueId allInvocations_Bool1 = TSymbolUniqueId(2875);
+ static constexpr const TSymbolUniqueId allInvocationsEqual_Bool1 = TSymbolUniqueId(2876);
+ static constexpr const TSymbolUniqueId gl_DepthRangeParameters = TSymbolUniqueId(2877);
+ static constexpr const TSymbolUniqueId gl_DepthRange = TSymbolUniqueId(2878);
+ static constexpr const TSymbolUniqueId gl_NumSamples = TSymbolUniqueId(2879);
+ static constexpr const TSymbolUniqueId gl_NumSamplesES3_2 = TSymbolUniqueId(2880);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAttribs = TSymbolUniqueId(2881);
+ static constexpr const TSymbolUniqueId gl_MaxVertexUniformVectors = TSymbolUniqueId(2882);
+ static constexpr const TSymbolUniqueId gl_MaxVertexTextureImageUnits = TSymbolUniqueId(2883);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedTextureImageUnits = TSymbolUniqueId(2884);
+ static constexpr const TSymbolUniqueId gl_MaxTextureImageUnits = TSymbolUniqueId(2885);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentUniformVectors = TSymbolUniqueId(2886);
+ static constexpr const TSymbolUniqueId gl_MaxVaryingVectors = TSymbolUniqueId(2887);
+ static constexpr const TSymbolUniqueId gl_MaxDrawBuffers = TSymbolUniqueId(2888);
+ static constexpr const TSymbolUniqueId gl_MaxDualSourceDrawBuffersEXT = TSymbolUniqueId(2889);
+ static constexpr const TSymbolUniqueId gl_MaxVertexOutputVectors = TSymbolUniqueId(2890);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentInputVectors = TSymbolUniqueId(2891);
+ static constexpr const TSymbolUniqueId gl_MinProgramTexelOffset = TSymbolUniqueId(2892);
+ static constexpr const TSymbolUniqueId gl_MaxProgramTexelOffset = TSymbolUniqueId(2893);
+ static constexpr const TSymbolUniqueId gl_MaxImageUnits = TSymbolUniqueId(2894);
+ static constexpr const TSymbolUniqueId gl_MaxVertexImageUniforms = TSymbolUniqueId(2895);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentImageUniforms = TSymbolUniqueId(2896);
+ static constexpr const TSymbolUniqueId gl_MaxComputeImageUniforms = TSymbolUniqueId(2897);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedImageUniforms = TSymbolUniqueId(2898);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedShaderOutputResources =
+ TSymbolUniqueId(2899);
+ static constexpr const TSymbolUniqueId gl_MaxComputeWorkGroupCount = TSymbolUniqueId(2900);
+ static constexpr const TSymbolUniqueId gl_MaxComputeWorkGroupSize = TSymbolUniqueId(2901);
+ static constexpr const TSymbolUniqueId gl_MaxComputeUniformComponents = TSymbolUniqueId(2902);
+ static constexpr const TSymbolUniqueId gl_MaxComputeTextureImageUnits = TSymbolUniqueId(2903);
+ static constexpr const TSymbolUniqueId gl_MaxComputeAtomicCounters = TSymbolUniqueId(2904);
+ static constexpr const TSymbolUniqueId gl_MaxComputeAtomicCounterBuffers =
+ TSymbolUniqueId(2905);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAtomicCounters = TSymbolUniqueId(2906);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentAtomicCounters = TSymbolUniqueId(2907);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedAtomicCounters = TSymbolUniqueId(2908);
+ static constexpr const TSymbolUniqueId gl_MaxAtomicCounterBindings = TSymbolUniqueId(2909);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAtomicCounterBuffers = TSymbolUniqueId(2910);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentAtomicCounterBuffers =
+ TSymbolUniqueId(2911);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedAtomicCounterBuffers =
+ TSymbolUniqueId(2912);
+ static constexpr const TSymbolUniqueId gl_MaxAtomicCounterBufferSize = TSymbolUniqueId(2913);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryInputComponents = TSymbolUniqueId(2914);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryInputComponentsES3_2 =
+ TSymbolUniqueId(2915);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputComponents = TSymbolUniqueId(2916);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputComponentsES3_2 =
+ TSymbolUniqueId(2917);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryImageUniforms = TSymbolUniqueId(2918);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryImageUniformsES3_2 = TSymbolUniqueId(2919);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTextureImageUnits = TSymbolUniqueId(2920);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTextureImageUnitsES3_2 =
+ TSymbolUniqueId(2921);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputVertices = TSymbolUniqueId(2922);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputVerticesES3_2 =
+ TSymbolUniqueId(2923);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTotalOutputComponents =
+ TSymbolUniqueId(2924);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTotalOutputComponentsES3_2 =
+ TSymbolUniqueId(2925);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryUniformComponents = TSymbolUniqueId(2926);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryUniformComponentsES3_2 =
+ TSymbolUniqueId(2927);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounters = TSymbolUniqueId(2928);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCountersES3_2 =
+ TSymbolUniqueId(2929);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounterBuffers =
+ TSymbolUniqueId(2930);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(2931);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlInputComponents = TSymbolUniqueId(2932);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlInputComponentsES3_2 =
+ TSymbolUniqueId(2933);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlOutputComponents =
+ TSymbolUniqueId(2934);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlOutputComponentsES3_2 =
+ TSymbolUniqueId(2935);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTextureImageUnits =
+ TSymbolUniqueId(2936);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTextureImageUnitsES3_2 =
+ TSymbolUniqueId(2937);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlUniformComponents =
+ TSymbolUniqueId(2938);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlUniformComponentsES3_2 =
+ TSymbolUniqueId(2939);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTotalOutputComponents =
+ TSymbolUniqueId(2940);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTotalOutputComponentsES3_2 =
+ TSymbolUniqueId(2941);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlImageUniforms = TSymbolUniqueId(2942);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlImageUniformsES3_2 =
+ TSymbolUniqueId(2943);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounters = TSymbolUniqueId(2944);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCountersES3_2 =
+ TSymbolUniqueId(2945);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounterBuffers =
+ TSymbolUniqueId(2946);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(2947);
+ static constexpr const TSymbolUniqueId gl_MaxTessPatchComponents = TSymbolUniqueId(2948);
+ static constexpr const TSymbolUniqueId gl_MaxTessPatchComponentsES3_2 = TSymbolUniqueId(2949);
+ static constexpr const TSymbolUniqueId gl_MaxPatchVertices = TSymbolUniqueId(2950);
+ static constexpr const TSymbolUniqueId gl_MaxPatchVerticesES3_2 = TSymbolUniqueId(2951);
+ static constexpr const TSymbolUniqueId gl_MaxTessGenLevel = TSymbolUniqueId(2952);
+ static constexpr const TSymbolUniqueId gl_MaxTessGenLevelES3_2 = TSymbolUniqueId(2953);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationInputComponents =
+ TSymbolUniqueId(2954);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationInputComponentsES3_2 =
+ TSymbolUniqueId(2955);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationOutputComponents =
+ TSymbolUniqueId(2956);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationOutputComponentsES3_2 =
+ TSymbolUniqueId(2957);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationTextureImageUnits =
+ TSymbolUniqueId(2958);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationTextureImageUnitsES3_2 =
+ TSymbolUniqueId(2959);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationUniformComponents =
+ TSymbolUniqueId(2960);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationUniformComponentsES3_2 =
+ TSymbolUniqueId(2961);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationImageUniforms =
+ TSymbolUniqueId(2962);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationImageUniformsES3_2 =
+ TSymbolUniqueId(2963);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounters =
+ TSymbolUniqueId(2964);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCountersES3_2 =
+ TSymbolUniqueId(2965);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounterBuffers =
+ TSymbolUniqueId(2966);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(2967);
+ static constexpr const TSymbolUniqueId gl_MaxSamples = TSymbolUniqueId(2968);
+ static constexpr const TSymbolUniqueId gl_MaxSamplesES3_2 = TSymbolUniqueId(2969);
+ static constexpr const TSymbolUniqueId gl_MaxClipDistancesAPPLE = TSymbolUniqueId(2970);
+ static constexpr const TSymbolUniqueId gl_MaxCullDistancesEXT = TSymbolUniqueId(2971);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedClipAndCullDistancesEXT =
+ TSymbolUniqueId(2972);
+ static constexpr const TSymbolUniqueId gl_FragCoord = TSymbolUniqueId(2973);
+ static constexpr const TSymbolUniqueId gl_FrontFacing = TSymbolUniqueId(2974);
+ static constexpr const TSymbolUniqueId gl_PointCoord = TSymbolUniqueId(2975);
+ static constexpr const TSymbolUniqueId gl_FragColor = TSymbolUniqueId(2976);
+ static constexpr const TSymbolUniqueId gl_FragData = TSymbolUniqueId(2977);
+ static constexpr const TSymbolUniqueId gl_FragDepth = TSymbolUniqueId(2978);
+ static constexpr const TSymbolUniqueId gl_HelperInvocation = TSymbolUniqueId(2979);
+ static constexpr const TSymbolUniqueId gl_FragCoord300 = TSymbolUniqueId(2980);
+ static constexpr const TSymbolUniqueId gl_SecondaryFragColorEXT = TSymbolUniqueId(2981);
+ static constexpr const TSymbolUniqueId gl_SecondaryFragDataEXT = TSymbolUniqueId(2982);
+ static constexpr const TSymbolUniqueId gl_FragDepthEXT = TSymbolUniqueId(2983);
+ static constexpr const TSymbolUniqueId gl_LastFragData = TSymbolUniqueId(2984);
+ static constexpr const TSymbolUniqueId gl_LastFragColor = TSymbolUniqueId(2985);
+ static constexpr const TSymbolUniqueId gl_LastFragDataNV = TSymbolUniqueId(2986);
+ static constexpr const TSymbolUniqueId gl_LastFragColorARM = TSymbolUniqueId(2987);
+ static constexpr const TSymbolUniqueId gl_PrimitiveID = TSymbolUniqueId(2988);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDES3_2 = TSymbolUniqueId(2989);
+ static constexpr const TSymbolUniqueId gl_Layer = TSymbolUniqueId(2990);
+ static constexpr const TSymbolUniqueId gl_LayerES3_2 = TSymbolUniqueId(2991);
+ static constexpr const TSymbolUniqueId gl_SampleID = TSymbolUniqueId(2992);
+ static constexpr const TSymbolUniqueId gl_SampleIDES3_2 = TSymbolUniqueId(2993);
+ static constexpr const TSymbolUniqueId gl_SamplePosition = TSymbolUniqueId(2994);
+ static constexpr const TSymbolUniqueId gl_SamplePositionES3_2 = TSymbolUniqueId(2995);
+ static constexpr const TSymbolUniqueId gl_SampleMaskIn = TSymbolUniqueId(2996);
+ static constexpr const TSymbolUniqueId gl_SampleMaskInES3_2 = TSymbolUniqueId(2997);
+ static constexpr const TSymbolUniqueId gl_SampleMask = TSymbolUniqueId(2998);
+ static constexpr const TSymbolUniqueId gl_SampleMaskES3_2 = TSymbolUniqueId(2999);
+ static constexpr const TSymbolUniqueId gl_CullDistance = TSymbolUniqueId(3000);
+ static constexpr const TSymbolUniqueId gl_ClipDistance = TSymbolUniqueId(3001);
+ static constexpr const TSymbolUniqueId gl_Position = TSymbolUniqueId(3002);
+ static constexpr const TSymbolUniqueId gl_PointSize = TSymbolUniqueId(3003);
+ static constexpr const TSymbolUniqueId gl_InstanceID = TSymbolUniqueId(3004);
+ static constexpr const TSymbolUniqueId gl_InstanceIndex = TSymbolUniqueId(3005);
+ static constexpr const TSymbolUniqueId gl_VertexID = TSymbolUniqueId(3006);
+ static constexpr const TSymbolUniqueId gl_VertexIndex = TSymbolUniqueId(3007);
+ static constexpr const TSymbolUniqueId gl_ViewportIndex = TSymbolUniqueId(3008);
+ static constexpr const TSymbolUniqueId gl_LayerVS = TSymbolUniqueId(3009);
+ static constexpr const TSymbolUniqueId gl_PointSize300 = TSymbolUniqueId(3010);
+ static constexpr const TSymbolUniqueId gl_DrawID = TSymbolUniqueId(3011);
+ static constexpr const TSymbolUniqueId gl_BaseVertex = TSymbolUniqueId(3012);
+ static constexpr const TSymbolUniqueId gl_BaseInstance = TSymbolUniqueId(3013);
+ static constexpr const TSymbolUniqueId angle_BaseVertex = TSymbolUniqueId(3014);
+ static constexpr const TSymbolUniqueId angle_BaseInstance = TSymbolUniqueId(3015);
+ static constexpr const TSymbolUniqueId gl_ClipDistanceAPPLE = TSymbolUniqueId(3016);
+ static constexpr const TSymbolUniqueId gl_CullDistanceEXT = TSymbolUniqueId(3017);
+ static constexpr const TSymbolUniqueId gl_NumWorkGroups = TSymbolUniqueId(3018);
+ static constexpr const TSymbolUniqueId gl_WorkGroupSize = TSymbolUniqueId(3019);
+ static constexpr const TSymbolUniqueId gl_WorkGroupID = TSymbolUniqueId(3020);
+ static constexpr const TSymbolUniqueId gl_LocalInvocationID = TSymbolUniqueId(3021);
+ static constexpr const TSymbolUniqueId gl_GlobalInvocationID = TSymbolUniqueId(3022);
+ static constexpr const TSymbolUniqueId gl_LocalInvocationIndex = TSymbolUniqueId(3023);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDIn = TSymbolUniqueId(3024);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDInES3_2 = TSymbolUniqueId(3025);
+ static constexpr const TSymbolUniqueId gl_InvocationID = TSymbolUniqueId(3026);
+ static constexpr const TSymbolUniqueId gl_InvocationIDES3_2 = TSymbolUniqueId(3027);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDGS = TSymbolUniqueId(3028);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDGSES3_2 = TSymbolUniqueId(3029);
+ static constexpr const TSymbolUniqueId gl_LayerGS = TSymbolUniqueId(3030);
+ static constexpr const TSymbolUniqueId gl_LayerGSES3_2 = TSymbolUniqueId(3031);
+ static constexpr const TSymbolUniqueId gl_PerVertex = TSymbolUniqueId(3032);
+ static constexpr const TSymbolUniqueId gl_PerVertexES3_2 = TSymbolUniqueId(3033);
+ static constexpr const TSymbolUniqueId gl_in = TSymbolUniqueId(3034);
+ static constexpr const TSymbolUniqueId gl_inES3_2 = TSymbolUniqueId(3035);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutBlock = TSymbolUniqueId(3036);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutBlockES3_2 = TSymbolUniqueId(3037);
+ static constexpr const TSymbolUniqueId gl_PositionGS = TSymbolUniqueId(3038);
+ static constexpr const TSymbolUniqueId gl_PositionGSES3_2 = TSymbolUniqueId(3039);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTCS = TSymbolUniqueId(3040);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTCSES3_2 = TSymbolUniqueId(3041);
+ static constexpr const TSymbolUniqueId gl_InvocationIDTCS = TSymbolUniqueId(3042);
+ static constexpr const TSymbolUniqueId gl_InvocationIDTCSES3_2 = TSymbolUniqueId(3043);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTCS = TSymbolUniqueId(3044);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTCSES3_2 = TSymbolUniqueId(3045);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTCS = TSymbolUniqueId(3046);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTCSES3_2 = TSymbolUniqueId(3047);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTCS = TSymbolUniqueId(3048);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTCSES3_2 = TSymbolUniqueId(3049);
+ static constexpr const TSymbolUniqueId gl_PerVertexTCS = TSymbolUniqueId(3050);
+ static constexpr const TSymbolUniqueId gl_PerVertexTCSES3_2 = TSymbolUniqueId(3051);
+ static constexpr const TSymbolUniqueId gl_inTCS = TSymbolUniqueId(3052);
+ static constexpr const TSymbolUniqueId gl_inTCSES3_2 = TSymbolUniqueId(3053);
+ static constexpr const TSymbolUniqueId gl_outTCS = TSymbolUniqueId(3054);
+ static constexpr const TSymbolUniqueId gl_outTCSES3_2 = TSymbolUniqueId(3055);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxTCS = TSymbolUniqueId(3056);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxTCSES3_2 = TSymbolUniqueId(3057);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTcsBlock = TSymbolUniqueId(3058);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTcsBlockES3_2 = TSymbolUniqueId(3059);
+ static constexpr const TSymbolUniqueId gl_PositionTCS = TSymbolUniqueId(3060);
+ static constexpr const TSymbolUniqueId gl_PositionTCSES3_2 = TSymbolUniqueId(3061);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxEXTTCS = TSymbolUniqueId(3062);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxEXTTCSES3_2 = TSymbolUniqueId(3063);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxOESTCS = TSymbolUniqueId(3064);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxOESTCSES3_2 = TSymbolUniqueId(3065);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTES = TSymbolUniqueId(3066);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTESES3_2 = TSymbolUniqueId(3067);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTES = TSymbolUniqueId(3068);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTESES3_2 = TSymbolUniqueId(3069);
+ static constexpr const TSymbolUniqueId gl_TessCoord = TSymbolUniqueId(3070);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTES = TSymbolUniqueId(3071);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTESES3_2 = TSymbolUniqueId(3072);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTES = TSymbolUniqueId(3073);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTESES3_2 = TSymbolUniqueId(3074);
+ static constexpr const TSymbolUniqueId gl_PerVertexTES = TSymbolUniqueId(3075);
+ static constexpr const TSymbolUniqueId gl_PerVertexTESES3_2 = TSymbolUniqueId(3076);
+ static constexpr const TSymbolUniqueId gl_inTES = TSymbolUniqueId(3077);
+ static constexpr const TSymbolUniqueId gl_inTESES3_2 = TSymbolUniqueId(3078);
+ static constexpr const TSymbolUniqueId gl_outTES = TSymbolUniqueId(3079);
+ static constexpr const TSymbolUniqueId gl_outTESES3_2 = TSymbolUniqueId(3080);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTesBlock = TSymbolUniqueId(3081);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTesBlockES3_2 = TSymbolUniqueId(3082);
+ static constexpr const TSymbolUniqueId gl_PositionTES = TSymbolUniqueId(3083);
+ static constexpr const TSymbolUniqueId gl_PositionTESES3_2 = TSymbolUniqueId(3084);
+ static constexpr const TSymbolUniqueId gl_ViewID_OVR = TSymbolUniqueId(3085);
+
+}; // class BuiltInId
+
+namespace BuiltInVariable
+{
+
+const TVariable *angle_BaseInstance();
+const TVariable *angle_BaseVertex();
+const TVariable *gl_BaseInstance();
+const TVariable *gl_BaseVertex();
+const TVariable *gl_DrawID();
+const TVariable *gl_FragColor();
+const TVariable *gl_FragCoord();
+const TVariable *gl_FragCoord300();
+const TVariable *gl_FragDepth();
+const TVariable *gl_FrontFacing();
+const TVariable *gl_GlobalInvocationID();
+const TVariable *gl_HelperInvocation();
+const TVariable *gl_InstanceID();
+const TVariable *gl_InstanceIndex();
+const TVariable *gl_InvocationID();
+const TVariable *gl_InvocationIDES3_2();
+const TVariable *gl_InvocationIDTCS();
+const TVariable *gl_InvocationIDTCSES3_2();
+const TVariable *gl_LastFragColor();
+const TVariable *gl_LastFragColorARM();
+const TVariable *gl_Layer();
+const TVariable *gl_LayerES3_2();
+const TVariable *gl_LayerGS();
+const TVariable *gl_LayerGSES3_2();
+const TVariable *gl_LayerVS();
+const TVariable *gl_LocalInvocationID();
+const TVariable *gl_LocalInvocationIndex();
+const TVariable *gl_NumSamples();
+const TVariable *gl_NumSamplesES3_2();
+const TVariable *gl_NumWorkGroups();
+const TVariable *gl_PatchVerticesInTCS();
+const TVariable *gl_PatchVerticesInTCSES3_2();
+const TVariable *gl_PatchVerticesInTES();
+const TVariable *gl_PatchVerticesInTESES3_2();
+const TVariable *gl_PointCoord();
+const TVariable *gl_PointSize();
+const TVariable *gl_PointSize300();
+const TVariable *gl_Position();
+const TVariable *gl_PrimitiveID();
+const TVariable *gl_PrimitiveIDES3_2();
+const TVariable *gl_PrimitiveIDGS();
+const TVariable *gl_PrimitiveIDGSES3_2();
+const TVariable *gl_PrimitiveIDIn();
+const TVariable *gl_PrimitiveIDInES3_2();
+const TVariable *gl_PrimitiveIDTCS();
+const TVariable *gl_PrimitiveIDTCSES3_2();
+const TVariable *gl_PrimitiveIDTES();
+const TVariable *gl_PrimitiveIDTESES3_2();
+const TVariable *gl_SampleID();
+const TVariable *gl_SampleIDES3_2();
+const TVariable *gl_SamplePosition();
+const TVariable *gl_SamplePositionES3_2();
+const TVariable *gl_SecondaryFragColorEXT();
+const TVariable *gl_TessCoord();
+const TVariable *gl_VertexID();
+const TVariable *gl_VertexIndex();
+const TVariable *gl_ViewID_OVR();
+const TVariable *gl_ViewportIndex();
+const TVariable *gl_WorkGroupID();
+const TVariable *gl_WorkGroupSize();
+
+} // namespace BuiltInVariable
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.cpp
new file mode 100644
index 0000000000..9cf4dddcd0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.cpp
@@ -0,0 +1,435 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// DriverUniform.cpp: Add code to support driver uniforms
+//
+
+#include "compiler/translator/tree_util/DriverUniform.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr ImmutableString kEmulatedDepthRangeParams = ImmutableString("ANGLEDepthRangeParams");
+
+constexpr const char kAcbBufferOffsets[] = "acbBufferOffsets";
+constexpr const char kDepthRange[] = "depthRange";
+constexpr const char kRenderArea[] = "renderArea";
+constexpr const char kFlipXY[] = "flipXY";
+constexpr const char kDither[] = "dither";
+constexpr const char kMisc[] = "misc";
+
+// Extended uniforms
+constexpr const char kXfbBufferOffsets[] = "xfbBufferOffsets";
+constexpr const char kXfbVerticesPerInstance[] = "xfbVerticesPerInstance";
+constexpr const char kUnused[] = "unused";
+constexpr const char kUnused2[] = "unused2";
+} // anonymous namespace
+
+// Class DriverUniform
+bool DriverUniform::addComputeDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ constexpr size_t kNumComputeDriverUniforms = 1;
+ constexpr std::array<const char *, kNumComputeDriverUniforms> kComputeDriverUniformNames = {
+ {kAcbBufferOffsets}};
+
+ ASSERT(!mDriverUniforms);
+ // This field list mirrors the structure of ComputeDriverUniforms in ContextVk.cpp.
+ TFieldList *driverFieldList = new TFieldList;
+
+ const std::array<TType *, kNumComputeDriverUniforms> kDriverUniformTypes = {{
+ new TType(EbtUInt, EbpHigh, EvqGlobal, 4),
+ }};
+
+ for (size_t uniformIndex = 0; uniformIndex < kNumComputeDriverUniforms; ++uniformIndex)
+ {
+ TField *driverUniformField =
+ new TField(kDriverUniformTypes[uniformIndex],
+ ImmutableString(kComputeDriverUniformNames[uniformIndex]), TSourceLoc(),
+ SymbolType::AngleInternal);
+ driverFieldList->push_back(driverUniformField);
+ }
+
+ // Define a driver uniform block "ANGLEUniformBlock" with instance name "ANGLEUniforms".
+ TLayoutQualifier layoutQualifier = TLayoutQualifier::Create();
+ layoutQualifier.blockStorage = EbsStd140;
+ layoutQualifier.pushConstant = true;
+
+ mDriverUniforms = DeclareInterfaceBlock(root, symbolTable, driverFieldList, EvqUniform,
+ layoutQualifier, TMemoryQualifier::Create(), 0,
+ ImmutableString(vk::kDriverUniformsBlockName),
+ ImmutableString(vk::kDriverUniformsVarName));
+ return mDriverUniforms != nullptr;
+}
+
+TFieldList *DriverUniform::createUniformFields(TSymbolTable *symbolTable)
+{
+ constexpr size_t kNumGraphicsDriverUniforms = 6;
+ constexpr std::array<const char *, kNumGraphicsDriverUniforms> kGraphicsDriverUniformNames = {{
+ kAcbBufferOffsets,
+ kDepthRange,
+ kRenderArea,
+ kFlipXY,
+ kDither,
+ kMisc,
+ }};
+
+ // This field list mirrors the structure of GraphicsDriverUniforms in ContextVk.cpp.
+ TFieldList *driverFieldList = new TFieldList;
+
+ const std::array<TType *, kNumGraphicsDriverUniforms> kDriverUniformTypes = {{
+ // acbBufferOffsets: Packed ubyte8
+ new TType(EbtUInt, EbpHigh, EvqGlobal, 2),
+ // depthRange: Near and far depth
+ new TType(EbtFloat, EbpHigh, EvqGlobal, 2),
+ // renderArea: Packed ushort2
+ new TType(EbtUInt, EbpHigh, EvqGlobal),
+ // flipXY: Packed snorm4
+ new TType(EbtUInt, EbpHigh, EvqGlobal),
+ // dither: ushort
+ new TType(EbtUInt, EbpHigh, EvqGlobal),
+ // misc: Various bits of state
+ new TType(EbtUInt, EbpHigh, EvqGlobal),
+ }};
+
+ for (size_t uniformIndex = 0; uniformIndex < kNumGraphicsDriverUniforms; ++uniformIndex)
+ {
+ TField *driverUniformField =
+ new TField(kDriverUniformTypes[uniformIndex],
+ ImmutableString(kGraphicsDriverUniformNames[uniformIndex]), TSourceLoc(),
+ SymbolType::AngleInternal);
+ driverFieldList->push_back(driverUniformField);
+ }
+
+ return driverFieldList;
+}
+
+const TType *DriverUniform::createEmulatedDepthRangeType(TSymbolTable *symbolTable)
+{
+ // If already defined, return it immediately.
+ if (mEmulatedDepthRangeType != nullptr)
+ {
+ return mEmulatedDepthRangeType;
+ }
+
+ // Create the depth range type.
+ TFieldList *depthRangeParamsFields = new TFieldList();
+ TType *floatType = new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1);
+ depthRangeParamsFields->push_back(
+ new TField(floatType, ImmutableString("near"), TSourceLoc(), SymbolType::AngleInternal));
+ depthRangeParamsFields->push_back(
+ new TField(floatType, ImmutableString("far"), TSourceLoc(), SymbolType::AngleInternal));
+ depthRangeParamsFields->push_back(
+ new TField(floatType, ImmutableString("diff"), TSourceLoc(), SymbolType::AngleInternal));
+
+ TStructure *emulatedDepthRangeParams = new TStructure(
+ symbolTable, kEmulatedDepthRangeParams, depthRangeParamsFields, SymbolType::AngleInternal);
+
+ mEmulatedDepthRangeType = new TType(emulatedDepthRangeParams, false);
+
+ return mEmulatedDepthRangeType;
+}
+
+// The Add*DriverUniformsToShader operation adds an internal uniform block to a shader. The driver
+// block is used to implement Vulkan-specific features and workarounds. Returns the driver uniforms
+// variable.
+//
+// There are Graphics and Compute variations as they require different uniforms.
+bool DriverUniform::addGraphicsDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ ASSERT(!mDriverUniforms);
+
+ // Declare the depth range struct type.
+ const TType *emulatedDepthRangeType = createEmulatedDepthRangeType(symbolTable);
+ const TType *emulatedDepthRangeDeclType = new TType(emulatedDepthRangeType->getStruct(), true);
+
+ const TVariable *depthRangeVar =
+ new TVariable(symbolTable->nextUniqueId(), kEmptyImmutableString, SymbolType::Empty,
+ TExtension::UNDEFINED, emulatedDepthRangeDeclType);
+
+ DeclareGlobalVariable(root, depthRangeVar);
+
+ TFieldList *driverFieldList = createUniformFields(symbolTable);
+ if (mMode == DriverUniformMode::InterfaceBlock)
+ {
+ // Define a driver uniform block "ANGLEUniformBlock" with instance name "ANGLEUniforms".
+ TLayoutQualifier layoutQualifier = TLayoutQualifier::Create();
+ layoutQualifier.blockStorage = EbsStd140;
+ layoutQualifier.pushConstant = true;
+
+ mDriverUniforms = DeclareInterfaceBlock(root, symbolTable, driverFieldList, EvqUniform,
+ layoutQualifier, TMemoryQualifier::Create(), 0,
+ ImmutableString(vk::kDriverUniformsBlockName),
+ ImmutableString(vk::kDriverUniformsVarName));
+ }
+ else
+ {
+ // Declare a structure "ANGLEUniformBlock" with instance name "ANGLE_angleUniforms".
+ // This code path is taken only by the direct-to-Metal backend, and the assumptions
+ // about the naming conventions of ANGLE-internal variables run too deeply to rename
+ // this one.
+ auto varName = ImmutableString("ANGLE_angleUniforms");
+ auto result = DeclareStructure(root, symbolTable, driverFieldList, EvqUniform,
+ TMemoryQualifier::Create(), 0,
+ ImmutableString(vk::kDriverUniformsBlockName), &varName);
+ mDriverUniforms = result.second;
+ }
+
+ return mDriverUniforms != nullptr;
+}
+
+TIntermTyped *DriverUniform::createDriverUniformRef(const char *fieldName) const
+{
+ size_t fieldIndex = 0;
+ if (mMode == DriverUniformMode::InterfaceBlock)
+ {
+ fieldIndex =
+ FindFieldIndex(mDriverUniforms->getType().getInterfaceBlock()->fields(), fieldName);
+ }
+ else
+ {
+ fieldIndex = FindFieldIndex(mDriverUniforms->getType().getStruct()->fields(), fieldName);
+ }
+
+ TIntermSymbol *angleUniformsRef = new TIntermSymbol(mDriverUniforms);
+ TConstantUnion *uniformIndex = new TConstantUnion;
+ uniformIndex->setIConst(static_cast<int>(fieldIndex));
+ TIntermConstantUnion *indexRef =
+ new TIntermConstantUnion(uniformIndex, *StaticType::GetBasic<EbtInt, EbpLow>());
+ if (mMode == DriverUniformMode::InterfaceBlock)
+ {
+ return new TIntermBinary(EOpIndexDirectInterfaceBlock, angleUniformsRef, indexRef);
+ }
+ return new TIntermBinary(EOpIndexDirectStruct, angleUniformsRef, indexRef);
+}
+
+TIntermTyped *DriverUniform::getAcbBufferOffsets() const
+{
+ return createDriverUniformRef(kAcbBufferOffsets);
+}
+
+TIntermTyped *DriverUniform::getDepthRange() const
+{
+ ASSERT(mEmulatedDepthRangeType != nullptr);
+
+ TIntermTyped *depthRangeRef = createDriverUniformRef(kDepthRange);
+ TIntermTyped *nearRef = new TIntermSwizzle(depthRangeRef, {0});
+ TIntermTyped *farRef = new TIntermSwizzle(depthRangeRef->deepCopy(), {1});
+ TIntermTyped *diff = new TIntermBinary(EOpSub, farRef, nearRef);
+
+ TIntermSequence args = {
+ nearRef->deepCopy(),
+ farRef->deepCopy(),
+ diff,
+ };
+
+ return TIntermAggregate::CreateConstructor(*mEmulatedDepthRangeType, &args);
+}
+
+TIntermTyped *DriverUniform::getViewportZScale() const
+{
+ ASSERT(mEmulatedDepthRangeType != nullptr);
+
+ TIntermTyped *depthRangeRef = createDriverUniformRef(kDepthRange);
+ TIntermTyped *nearRef = new TIntermSwizzle(depthRangeRef, {0});
+ TIntermTyped *farRef = new TIntermSwizzle(depthRangeRef->deepCopy(), {1});
+
+ TIntermTyped *isNegative = new TIntermBinary(EOpLessThan, farRef, nearRef);
+
+ return new TIntermTernary(isNegative, CreateFloatNode(-1, EbpMedium),
+ CreateFloatNode(1, EbpMedium));
+}
+
+TIntermTyped *DriverUniform::getHalfRenderArea() const
+{
+ TIntermTyped *renderAreaRef = createDriverUniformRef(kRenderArea);
+ TIntermTyped *width = new TIntermBinary(EOpBitwiseAnd, renderAreaRef, CreateUIntNode(0xFFFF));
+ TIntermTyped *height =
+ new TIntermBinary(EOpBitShiftRight, renderAreaRef->deepCopy(), CreateUIntNode(16));
+
+ TIntermSequence widthArgs = {
+ width,
+ };
+ TIntermTyped *widthAsFloat =
+ TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtFloat, EbpHigh>(), &widthArgs);
+
+ TIntermSequence heightArgs = {
+ height,
+ };
+ TIntermTyped *heightAsFloat = TIntermAggregate::CreateConstructor(
+ *StaticType::GetBasic<EbtFloat, EbpHigh>(), &heightArgs);
+
+ TIntermSequence args = {
+ widthAsFloat,
+ heightAsFloat,
+ };
+
+ TIntermTyped *renderArea =
+ TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtFloat, EbpHigh, 2>(), &args);
+ return new TIntermBinary(EOpVectorTimesScalar, renderArea, CreateFloatNode(0.5, EbpMedium));
+}
+
+TIntermTyped *DriverUniform::getFlipXY(TSymbolTable *symbolTable, DriverUniformFlip stage) const
+{
+ TIntermTyped *flipXY = createDriverUniformRef(kFlipXY);
+ TIntermTyped *values = CreateBuiltInUnaryFunctionCallNode(
+ "unpackSnorm4x8", flipXY, *symbolTable,
+ GetESSLOrGLSLVersion(symbolTable->getShaderSpec(), 310, 400));
+
+ if (stage == DriverUniformFlip::Fragment)
+ {
+ return new TIntermSwizzle(values, {0, 1});
+ }
+
+ return new TIntermSwizzle(values, {2, 3});
+}
+
+TIntermTyped *DriverUniform::getNegFlipXY(TSymbolTable *symbolTable, DriverUniformFlip stage) const
+{
+ TIntermTyped *flipXY = getFlipXY(symbolTable, stage);
+
+ constexpr std::array<float, 2> kMultiplier = {1, -1};
+ return new TIntermBinary(EOpMul, flipXY, CreateVecNode(kMultiplier.data(), 2, EbpLow));
+}
+
+TIntermTyped *DriverUniform::getDither() const
+{
+ return createDriverUniformRef(kDither);
+}
+
+TIntermTyped *DriverUniform::getSwapXY() const
+{
+ TIntermTyped *miscRef = createDriverUniformRef(kMisc);
+ TIntermTyped *swapXY = new TIntermBinary(EOpBitwiseAnd, miscRef,
+ CreateUIntNode(vk::kDriverUniformsMiscSwapXYMask));
+
+ TIntermSequence args = {
+ swapXY,
+ };
+ return TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtBool, EbpUndefined>(),
+ &args);
+}
+
+TIntermTyped *DriverUniform::getAdvancedBlendEquation() const
+{
+ TIntermTyped *miscRef = createDriverUniformRef(kMisc);
+ TIntermTyped *equation =
+ new TIntermBinary(EOpBitShiftRight, miscRef,
+ CreateUIntNode(vk::kDriverUniformsMiscAdvancedBlendEquationOffset));
+ equation = new TIntermBinary(EOpBitwiseAnd, equation,
+ CreateUIntNode(vk::kDriverUniformsMiscAdvancedBlendEquationMask));
+
+ return equation;
+}
+
+TIntermTyped *DriverUniform::getNumSamples() const
+{
+ TIntermTyped *miscRef = createDriverUniformRef(kMisc);
+ TIntermTyped *sampleCount = new TIntermBinary(
+ EOpBitShiftRight, miscRef, CreateUIntNode(vk::kDriverUniformsMiscSampleCountOffset));
+ sampleCount = new TIntermBinary(EOpBitwiseAnd, sampleCount,
+ CreateUIntNode(vk::kDriverUniformsMiscSampleCountMask));
+
+ return sampleCount;
+}
+
+TIntermTyped *DriverUniform::getClipDistancesEnabled() const
+{
+ TIntermTyped *miscRef = createDriverUniformRef(kMisc);
+ TIntermTyped *enabledMask = new TIntermBinary(
+ EOpBitShiftRight, miscRef, CreateUIntNode(vk::kDriverUniformsMiscEnabledClipPlanesOffset));
+ enabledMask = new TIntermBinary(EOpBitwiseAnd, enabledMask,
+ CreateUIntNode(vk::kDriverUniformsMiscEnabledClipPlanesMask));
+
+ return enabledMask;
+}
+
+TIntermTyped *DriverUniform::getTransformDepth() const
+{
+ TIntermTyped *miscRef = createDriverUniformRef(kMisc);
+ TIntermTyped *transformDepth = new TIntermBinary(
+ EOpBitShiftRight, miscRef, CreateUIntNode(vk::kDriverUniformsMiscTransformDepthOffset));
+ transformDepth = new TIntermBinary(EOpBitwiseAnd, transformDepth,
+ CreateUIntNode(vk::kDriverUniformsMiscTransformDepthMask));
+
+ TIntermSequence args = {
+ transformDepth,
+ };
+ return TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtBool, EbpUndefined>(),
+ &args);
+}
+
+//
+// Class DriverUniformExtended
+//
+TFieldList *DriverUniformExtended::createUniformFields(TSymbolTable *symbolTable)
+{
+ TFieldList *driverFieldList = DriverUniform::createUniformFields(symbolTable);
+
+ constexpr size_t kNumGraphicsDriverUniformsExt = 4;
+ constexpr std::array<const char *, kNumGraphicsDriverUniformsExt>
+ kGraphicsDriverUniformNamesExt = {
+ {kXfbBufferOffsets, kXfbVerticesPerInstance, kUnused, kUnused2}};
+
+ const std::array<TType *, kNumGraphicsDriverUniformsExt> kDriverUniformTypesExt = {{
+ // xfbBufferOffsets: uvec4
+ new TType(EbtInt, EbpHigh, EvqGlobal, 4),
+ // xfbVerticesPerInstance: uint
+ new TType(EbtInt, EbpHigh, EvqGlobal),
+ // unused: uvec3
+ new TType(EbtUInt, EbpHigh, EvqGlobal),
+ new TType(EbtUInt, EbpHigh, EvqGlobal, 2),
+ }};
+
+ for (size_t uniformIndex = 0; uniformIndex < kNumGraphicsDriverUniformsExt; ++uniformIndex)
+ {
+ TField *driverUniformField =
+ new TField(kDriverUniformTypesExt[uniformIndex],
+ ImmutableString(kGraphicsDriverUniformNamesExt[uniformIndex]), TSourceLoc(),
+ SymbolType::AngleInternal);
+ driverFieldList->push_back(driverUniformField);
+ }
+
+ return driverFieldList;
+}
+
+TIntermTyped *DriverUniformExtended::getXfbBufferOffsets() const
+{
+ return createDriverUniformRef(kXfbBufferOffsets);
+}
+
+TIntermTyped *DriverUniformExtended::getXfbVerticesPerInstance() const
+{
+ return createDriverUniformRef(kXfbVerticesPerInstance);
+}
+
+TIntermTyped *MakeSwapXMultiplier(TIntermTyped *swapped)
+{
+ // float(!swapped)
+ TIntermSequence args = {
+ new TIntermUnary(EOpLogicalNot, swapped, nullptr),
+ };
+ return TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtFloat, EbpLow>(), &args);
+}
+
+TIntermTyped *MakeSwapYMultiplier(TIntermTyped *swapped)
+{
+ // float(swapped)
+ TIntermSequence args = {
+ swapped,
+ };
+ return TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtFloat, EbpLow>(), &args);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.h b/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.h
new file mode 100644
index 0000000000..53eebae74d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.h
@@ -0,0 +1,110 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// DriverUniform.h: Add code to support driver uniforms
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_DRIVERUNIFORM_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_DRIVERUNIFORM_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TIntermNode;
+class TSymbolTable;
+class TIntermTyped;
+class TIntermSwizzle;
+class TIntermBinary;
+
+enum class DriverUniformMode
+{
+ // Define the driver uniforms as an interface block. Used by the
+ // Vulkan and Metal/SPIR-V backends.
+ InterfaceBlock,
+
+ // Define the driver uniforms as a structure. Used by the
+ // direct-to-MSL Metal backend.
+ Structure
+};
+
+enum class DriverUniformFlip
+{
+ // Flip uniforms for fragment shaders
+ Fragment,
+ // Flip uniforms for pre-rasterization stages. These differ from the fragment values by whether
+ // the viewport needs to be flipped, and whether negative viewports are supported.
+ PreFragment,
+};
+
+class DriverUniform
+{
+ public:
+ DriverUniform(DriverUniformMode mode)
+ : mMode(mode), mDriverUniforms(nullptr), mEmulatedDepthRangeType(nullptr)
+ {}
+ virtual ~DriverUniform() = default;
+
+ bool addComputeDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable);
+ bool addGraphicsDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable);
+
+ TIntermTyped *getAcbBufferOffsets() const;
+ TIntermTyped *getDepthRange() const;
+ TIntermTyped *getViewportZScale() const;
+ TIntermTyped *getHalfRenderArea() const;
+ TIntermTyped *getFlipXY(TSymbolTable *symbolTable, DriverUniformFlip stage) const;
+ // Returns vec2(flip.x, -flip.y)
+ TIntermTyped *getNegFlipXY(TSymbolTable *symbolTable, DriverUniformFlip stage) const;
+ TIntermTyped *getDither() const;
+ TIntermTyped *getSwapXY() const;
+ TIntermTyped *getAdvancedBlendEquation() const;
+ TIntermTyped *getNumSamples() const;
+ TIntermTyped *getClipDistancesEnabled() const;
+ TIntermTyped *getTransformDepth() const;
+
+ virtual TIntermTyped *getViewport() const { return nullptr; }
+ virtual TIntermTyped *getXfbBufferOffsets() const { return nullptr; }
+ virtual TIntermTyped *getXfbVerticesPerInstance() const { return nullptr; }
+
+ const TVariable *getDriverUniformsVariable() const { return mDriverUniforms; }
+
+ protected:
+ TIntermTyped *createDriverUniformRef(const char *fieldName) const;
+ virtual TFieldList *createUniformFields(TSymbolTable *symbolTable);
+ const TType *createEmulatedDepthRangeType(TSymbolTable *symbolTable);
+
+ const DriverUniformMode mMode;
+ const TVariable *mDriverUniforms;
+ TType *mEmulatedDepthRangeType;
+};
+
+class DriverUniformExtended : public DriverUniform
+{
+ public:
+ DriverUniformExtended(DriverUniformMode mode) : DriverUniform(mode) {}
+ ~DriverUniformExtended() override {}
+
+ TIntermTyped *getXfbBufferOffsets() const override;
+ TIntermTyped *getXfbVerticesPerInstance() const override;
+
+ protected:
+ TFieldList *createUniformFields(TSymbolTable *symbolTable) override;
+};
+
+// Returns either (1,0) or (0,1) based on whether X and Y should remain as-is or swapped
+// respectively. dot((x,y), multiplier) will yield x, and dot((x,y), multiplier.yx) will yield y in
+// the possibly-swapped coordinates.
+//
+// Each component is separately returned by a function
+TIntermTyped *MakeSwapXMultiplier(TIntermTyped *swapped);
+TIntermTyped *MakeSwapYMultiplier(TIntermTyped *swapped);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_DRIVERUNIFORM_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.cpp
new file mode 100644
index 0000000000..198040df14
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.cpp
@@ -0,0 +1,32 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FindFunction.cpp: Find functions.
+
+#include "compiler/translator/tree_util/FindFunction.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+
+namespace sh
+{
+
+size_t FindFirstFunctionDefinitionIndex(TIntermBlock *root)
+{
+ const TIntermSequence &sequence = *root->getSequence();
+ for (size_t index = 0; index < sequence.size(); ++index)
+ {
+ TIntermNode *node = sequence[index];
+ TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition();
+ if (nodeFunction != nullptr)
+ {
+ return index;
+ }
+ }
+ return std::numeric_limits<size_t>::max();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.h b/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.h
new file mode 100644
index 0000000000..ced6b7e96e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.h
@@ -0,0 +1,21 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FindFunction.h: Adds functions to find functions
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_FINDFUNCTION_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_FINDFUNCTION_H_
+
+#include <cstddef>
+
+namespace sh
+{
+class TIntermBlock;
+
+size_t FindFirstFunctionDefinitionIndex(TIntermBlock *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_FINDFUNCTION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.cpp
new file mode 100644
index 0000000000..833948602a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.cpp
@@ -0,0 +1,54 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FindMain.cpp: Find the main() function definition in a given AST.
+
+#include "compiler/translator/tree_util/FindMain.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+
+namespace sh
+{
+
+size_t FindMainIndex(TIntermBlock *root)
+{
+ const TIntermSequence &sequence = *root->getSequence();
+ for (size_t index = 0; index < sequence.size(); ++index)
+ {
+ TIntermNode *node = sequence[index];
+ TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition();
+ if (nodeFunction != nullptr && nodeFunction->getFunction()->isMain())
+ {
+ return index;
+ }
+ }
+ return std::numeric_limits<size_t>::max();
+}
+
+TIntermFunctionDefinition *FindMain(TIntermBlock *root)
+{
+ for (TIntermNode *node : *root->getSequence())
+ {
+ TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition();
+ if (nodeFunction != nullptr && nodeFunction->getFunction()->isMain())
+ {
+ return nodeFunction;
+ }
+ }
+ return nullptr;
+}
+
+TIntermBlock *FindMainBody(TIntermBlock *root)
+{
+ TIntermFunctionDefinition *main = FindMain(root);
+ ASSERT(main != nullptr);
+ TIntermBlock *mainBody = main->getBody();
+ ASSERT(mainBody != nullptr);
+ return mainBody;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.h b/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.h
new file mode 100644
index 0000000000..bbdcbe978a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FindMain.h: Adds functions to get the main function definition and its body.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_
+
+#include <cstddef>
+
+namespace sh
+{
+class TIntermBlock;
+class TIntermFunctionDefinition;
+
+size_t FindMainIndex(TIntermBlock *root);
+TIntermFunctionDefinition *FindMain(TIntermBlock *root);
+TIntermBlock *FindMainBody(TIntermBlock *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.cpp
new file mode 100644
index 0000000000..2943117314
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.cpp
@@ -0,0 +1,703 @@
+//
+// Copyright 2021 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FindPreciseNodes.cpp: Propagates |precise| to AST nodes.
+//
+// The high level algorithm is as follows. For every node that "assigns" to a precise object,
+// subobject (a precise struct whose field is being assigned) or superobject (a struct with a
+// precise field), two things happen:
+//
+// - The operation is marked precise if it's an arithmetic operation
+// - The right hand side of the assignment is made precise. If only a subobject is precise, only
+// the corresponding subobject of the right hand side is made precise.
+//
+
+#include "compiler/translator/tree_util/FindPreciseNodes.h"
+
+#include "common/hash_utils.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// An access chain applied to a variable. The |precise|-ness of a node does not change when
+// indexing arrays, selecting matrix columns or swizzle vectors. This access chain thus only
+// includes block field selections. The access chain is used to identify the part of an object
+// that is or should be |precise|. If both a.b.c and a.b are precise, only a.b is every considered.
+class AccessChain
+{
+ public:
+ AccessChain() = default;
+
+ bool operator==(const AccessChain &other) const { return mChain == other.mChain; }
+
+ const TVariable *build(TIntermTyped *lvalue);
+
+ const TVector<size_t> &getChain() const { return mChain; }
+
+ void reduceChain(size_t newSize)
+ {
+ ASSERT(newSize <= mChain.size());
+ mChain.resize(newSize);
+ }
+ void clear() { reduceChain(0); }
+ void push_back(size_t index) { mChain.push_back(index); }
+ void pop_front(size_t n);
+ void append(const AccessChain &other)
+ {
+ mChain.insert(mChain.end(), other.mChain.begin(), other.mChain.end());
+ }
+ bool removePrefix(const AccessChain &other);
+
+ private:
+ TVector<size_t> mChain;
+};
+
+bool IsIndexOp(TOperator op)
+{
+ switch (op)
+ {
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ case EOpIndexIndirect:
+ return true;
+ default:
+ return false;
+ }
+}
+
+const TVariable *AccessChain::build(TIntermTyped *lvalue)
+{
+ if (lvalue->getAsSwizzleNode())
+ {
+ return build(lvalue->getAsSwizzleNode()->getOperand());
+ }
+ if (lvalue->getAsSymbolNode())
+ {
+ const TVariable *var = &lvalue->getAsSymbolNode()->variable();
+
+ // For fields of nameless interface blocks, add the field index too.
+ if (var->getType().getInterfaceBlock() != nullptr)
+ {
+ mChain.push_back(var->getType().getInterfaceBlockFieldIndex());
+ }
+
+ return var;
+ }
+ TIntermBinary *binary = lvalue->getAsBinaryNode();
+ ASSERT(binary);
+
+ TOperator op = binary->getOp();
+ ASSERT(IsIndexOp(op));
+
+ const TVariable *var = build(binary->getLeft());
+
+ if (op == EOpIndexDirectStruct || op == EOpIndexDirectInterfaceBlock)
+ {
+ int fieldIndex = binary->getRight()->getAsConstantUnion()->getIConst(0);
+ mChain.push_back(fieldIndex);
+ }
+
+ return var;
+}
+
+void AccessChain::pop_front(size_t n)
+{
+ std::rotate(mChain.begin(), mChain.begin() + n, mChain.end());
+ reduceChain(mChain.size() - n);
+}
+
+bool AccessChain::removePrefix(const AccessChain &other)
+{
+ // First, make sure the common part of the two access chains match.
+ size_t commonSize = std::min(mChain.size(), other.mChain.size());
+
+ for (size_t index = 0; index < commonSize; ++index)
+ {
+ if (mChain[index] != other.mChain[index])
+ {
+ return false;
+ }
+ }
+
+ // Remove the common part from the access chain. If other is a deeper access chain, this access
+ // chain will become empty.
+ pop_front(commonSize);
+
+ return true;
+}
+
+AccessChain GetAssignmentAccessChain(TIntermOperator *node)
+{
+ // The assignment is either a unary or a binary node, and the lvalue is always the first child.
+ AccessChain lvalueAccessChain;
+ lvalueAccessChain.build(node->getChildNode(0)->getAsTyped());
+ return lvalueAccessChain;
+}
+
+template <typename Traverser>
+void TraverseIndexNodesOnly(TIntermNode *node, Traverser *traverser)
+{
+ if (node->getAsSwizzleNode())
+ {
+ node = node->getAsSwizzleNode()->getOperand();
+ }
+
+ if (node->getAsSymbolNode())
+ {
+ return;
+ }
+
+ TIntermBinary *binary = node->getAsBinaryNode();
+ ASSERT(binary);
+
+ TOperator op = binary->getOp();
+ ASSERT(IsIndexOp(op));
+
+ if (op == EOpIndexIndirect)
+ {
+ binary->getRight()->traverse(traverser);
+ }
+
+ TraverseIndexNodesOnly(binary->getLeft(), traverser);
+}
+
+// An object, which could be a sub-object of a variable.
+struct ObjectAndAccessChain
+{
+ const TVariable *variable;
+ AccessChain accessChain;
+};
+
+bool operator==(const ObjectAndAccessChain &a, const ObjectAndAccessChain &b)
+{
+ return a.variable == b.variable && a.accessChain == b.accessChain;
+}
+
+struct ObjectAndAccessChainHash
+{
+ size_t operator()(const ObjectAndAccessChain &object) const
+ {
+ size_t result = angle::ComputeGenericHash(&object.variable, sizeof(object.variable));
+ if (!object.accessChain.getChain().empty())
+ {
+ result =
+ result ^ angle::ComputeGenericHash(object.accessChain.getChain().data(),
+ object.accessChain.getChain().size() *
+ sizeof(object.accessChain.getChain()[0]));
+ }
+ return result;
+ }
+};
+
+// A map from variables to AST nodes that modify them (i.e. nodes where IsAssignment(op)).
+using VariableToAssignmentNodeMap = angle::HashMap<const TVariable *, TVector<TIntermOperator *>>;
+// A set of |return| nodes from functions with a |precise| return value.
+using PreciseReturnNodes = angle::HashSet<TIntermBranch *>;
+// A set of precise objects that need processing, or have been processed.
+using PreciseObjectSet = angle::HashSet<ObjectAndAccessChain, ObjectAndAccessChainHash>;
+
+struct ASTInfo
+{
+ // Generic information about the tree:
+ VariableToAssignmentNodeMap variableAssignmentNodeMap;
+ // Information pertaining to |precise| expressions:
+ PreciseReturnNodes preciseReturnNodes;
+ PreciseObjectSet preciseObjectsToProcess;
+ PreciseObjectSet preciseObjectsVisited;
+};
+
+int GetObjectPreciseSubChainLength(const ObjectAndAccessChain &object)
+{
+ const TType &type = object.variable->getType();
+
+ if (type.isPrecise())
+ {
+ return 0;
+ }
+
+ const TFieldListCollection *block = type.getInterfaceBlock();
+ if (block == nullptr)
+ {
+ block = type.getStruct();
+ }
+ const TVector<size_t> &accessChain = object.accessChain.getChain();
+
+ for (size_t length = 0; length < accessChain.size(); ++length)
+ {
+ ASSERT(block != nullptr);
+
+ const TField *field = block->fields()[accessChain[length]];
+ if (field->type()->isPrecise())
+ {
+ return static_cast<int>(length + 1);
+ }
+
+ block = field->type()->getStruct();
+ }
+
+ return -1;
+}
+
+void AddPreciseObject(ASTInfo *info, const ObjectAndAccessChain &object)
+{
+ if (info->preciseObjectsVisited.count(object) > 0)
+ {
+ return;
+ }
+
+ info->preciseObjectsToProcess.insert(object);
+ info->preciseObjectsVisited.insert(object);
+}
+
+void AddPreciseSubObjects(ASTInfo *info, const ObjectAndAccessChain &object);
+
+void AddObjectIfPrecise(ASTInfo *info, const ObjectAndAccessChain &object)
+{
+ // See if the access chain is already precise, and if so add the minimum access chain that is
+ // precise.
+ int preciseSubChainLength = GetObjectPreciseSubChainLength(object);
+ if (preciseSubChainLength == -1)
+ {
+ // If the access chain is not precise, see if there are any fields of it that are precise,
+ // and add those individually.
+ AddPreciseSubObjects(info, object);
+ return;
+ }
+
+ ObjectAndAccessChain preciseObject = object;
+ preciseObject.accessChain.reduceChain(preciseSubChainLength);
+
+ AddPreciseObject(info, preciseObject);
+}
+
+void AddPreciseSubObjects(ASTInfo *info, const ObjectAndAccessChain &object)
+{
+ const TFieldListCollection *block = object.variable->getType().getInterfaceBlock();
+ if (block == nullptr)
+ {
+ block = object.variable->getType().getStruct();
+ }
+ const TVector<size_t> &accessChain = object.accessChain.getChain();
+
+ for (size_t length = 0; length < accessChain.size(); ++length)
+ {
+ block = block->fields()[accessChain[length]]->type()->getStruct();
+ }
+
+ if (block == nullptr)
+ {
+ return;
+ }
+
+ for (size_t fieldIndex = 0; fieldIndex < block->fields().size(); ++fieldIndex)
+ {
+ ObjectAndAccessChain subObject = object;
+ subObject.accessChain.push_back(fieldIndex);
+
+ // If the field is precise, add it as a precise subobject. Otherwise recurse.
+ if (block->fields()[fieldIndex]->type()->isPrecise())
+ {
+ AddPreciseObject(info, subObject);
+ }
+ else
+ {
+ AddPreciseSubObjects(info, subObject);
+ }
+ }
+}
+
+bool IsArithmeticOp(TOperator op)
+{
+ switch (op)
+ {
+ case EOpNegative:
+
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+
+ case EOpAdd:
+ case EOpSub:
+ case EOpMul:
+ case EOpDiv:
+ case EOpIMod:
+
+ case EOpVectorTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpMatrixTimesMatrix:
+
+ case EOpAddAssign:
+ case EOpSubAssign:
+
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+
+ case EOpDivAssign:
+ case EOpIModAssign:
+
+ case EOpDot:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// A traverser that gathers the following information, used to kick off processing:
+//
+// - For each variable, the AST nodes that modify it.
+// - The set of |precise| return AST node.
+// - The set of |precise| access chains assigned to.
+//
+class InfoGatherTraverser : public TIntermTraverser
+{
+ public:
+ InfoGatherTraverser(ASTInfo *info) : TIntermTraverser(true, false, false), mInfo(info) {}
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override
+ {
+ // If the node is an assignment (i.e. ++ and --), store the relevant information.
+ if (!IsAssignment(node->getOp()))
+ {
+ return true;
+ }
+
+ visitLvalue(node, node->getOperand());
+ return false;
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ if (IsAssignment(node->getOp()))
+ {
+ visitLvalue(node, node->getLeft());
+
+ node->getRight()->traverse(this);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ TIntermSymbol *symbol = sequence.front()->getAsSymbolNode();
+ TIntermBinary *initNode = sequence.front()->getAsBinaryNode();
+ TIntermTyped *initExpression = nullptr;
+
+ if (symbol == nullptr)
+ {
+ ASSERT(initNode->getOp() == EOpInitialize);
+
+ symbol = initNode->getLeft()->getAsSymbolNode();
+ initExpression = initNode->getRight();
+ }
+
+ ASSERT(symbol);
+ ObjectAndAccessChain object = {&symbol->variable(), {}};
+ AddObjectIfPrecise(mInfo, object);
+
+ if (initExpression)
+ {
+ mInfo->variableAssignmentNodeMap[object.variable].push_back(initNode);
+
+ // Visit the init expression, which may itself have assignments.
+ initExpression->traverse(this);
+ }
+
+ return false;
+ }
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ mCurrentFunction = node->getFunction();
+
+ for (size_t paramIndex = 0; paramIndex < mCurrentFunction->getParamCount(); ++paramIndex)
+ {
+ ObjectAndAccessChain param = {mCurrentFunction->getParam(paramIndex), {}};
+ AddObjectIfPrecise(mInfo, param);
+ }
+
+ return true;
+ }
+
+ bool visitBranch(Visit visit, TIntermBranch *node) override
+ {
+ if (node->getFlowOp() == EOpReturn && node->getChildCount() == 1 &&
+ mCurrentFunction->getReturnType().isPrecise())
+ {
+ mInfo->preciseReturnNodes.insert(node);
+ }
+
+ return true;
+ }
+
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override
+ {
+ if (node->isPrecise())
+ {
+ ObjectAndAccessChain preciseObject = {&node->getSymbol()->variable(), {}};
+ AddPreciseObject(mInfo, preciseObject);
+ }
+
+ return false;
+ }
+
+ private:
+ void visitLvalue(TIntermOperator *assignmentNode, TIntermTyped *lvalueNode)
+ {
+ AccessChain lvalueChain;
+ const TVariable *lvalueBase = lvalueChain.build(lvalueNode);
+ mInfo->variableAssignmentNodeMap[lvalueBase].push_back(assignmentNode);
+
+ ObjectAndAccessChain lvalue = {lvalueBase, lvalueChain};
+ AddObjectIfPrecise(mInfo, lvalue);
+
+ TraverseIndexNodesOnly(lvalueNode, this);
+ }
+
+ ASTInfo *mInfo = nullptr;
+ const TFunction *mCurrentFunction = nullptr;
+};
+
+// A traverser that, given an access chain, traverses an expression and marks parts of it |precise|.
+// For example, in the expression |Struct1(a, Struct2(b, c), d)|:
+//
+// - Given access chain [1], both |b| and |c| are marked precise.
+// - Given access chain [1, 0], only |b| is marked precise.
+//
+// When access chain is empty, arithmetic nodes are marked |precise| and any access chains found in
+// their children is recursively added for processing.
+//
+// The access chain given to the traverser is derived from the left hand side of an assignment,
+// while the traverser is run on the right hand side.
+class PropagatePreciseTraverser : public TIntermTraverser
+{
+ public:
+ PropagatePreciseTraverser(ASTInfo *info) : TIntermTraverser(true, false, false), mInfo(info) {}
+
+ void propagatePrecise(TIntermNode *expression, const AccessChain &accessChain)
+ {
+ mCurrentAccessChain = accessChain;
+ expression->traverse(this);
+ }
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override
+ {
+ // Unary operations cannot be applied to structures.
+ ASSERT(mCurrentAccessChain.getChain().empty());
+
+ // Mark arithmetic nodes as |precise|.
+ if (IsArithmeticOp(node->getOp()))
+ {
+ node->setIsPrecise();
+ }
+
+ // Mark the operand itself |precise| too.
+ return true;
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ if (IsIndexOp(node->getOp()))
+ {
+ // Append the remaining access chain with that of the node, and mark that as |precise|.
+ // For example, if we are evaluating an expression and expecting to mark the access
+ // chain [1, 3] as |precise|, and the node itself has access chain [0, 2] applied to
+ // variable V, then what ends up being |precise| is V with access chain [0, 2, 1, 3].
+ AccessChain nodeAccessChain;
+ const TVariable *baseVariable = nodeAccessChain.build(node);
+ nodeAccessChain.append(mCurrentAccessChain);
+
+ ObjectAndAccessChain preciseObject = {baseVariable, nodeAccessChain};
+ AddPreciseObject(mInfo, preciseObject);
+
+ // Visit index nodes, each of which should be considered |precise| in its entirety.
+ mCurrentAccessChain.clear();
+ TraverseIndexNodesOnly(node, this);
+
+ return false;
+ }
+
+ if (node->getOp() == EOpComma)
+ {
+ // For expr1,expr2, consider only expr2 as that's the one whose calculation is relevant.
+ node->getRight()->traverse(this);
+ return false;
+ }
+
+ // Mark arithmetic nodes as |precise|.
+ if (IsArithmeticOp(node->getOp()))
+ {
+ node->setIsPrecise();
+ }
+
+ if (IsAssignment(node->getOp()) || node->getOp() == EOpInitialize)
+ {
+ // If the node itself is a[...] op= expr, consider only expr as |precise|, as that's the
+ // one whose calculation is significant.
+ node->getRight()->traverse(this);
+
+ // The indices used on the left hand side are also significant in their entirety.
+ mCurrentAccessChain.clear();
+ TraverseIndexNodesOnly(node->getLeft(), this);
+
+ return false;
+ }
+
+ // Binary operations cannot be applied to structures.
+ ASSERT(mCurrentAccessChain.getChain().empty());
+
+ // Mark the operands themselves |precise| too.
+ return true;
+ }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ // Mark the symbol together with the current access chain as |precise|.
+ ObjectAndAccessChain preciseObject = {&symbol->variable(), mCurrentAccessChain};
+ AddPreciseObject(mInfo, preciseObject);
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ // If this is a struct constructor and the access chain is not empty, only apply |precise|
+ // to the field selected by the access chain.
+ const TType &type = node->getType();
+ const bool isStructConstructor =
+ node->getOp() == EOpConstruct && type.getStruct() != nullptr && !type.isArray();
+
+ if (!mCurrentAccessChain.getChain().empty() && isStructConstructor)
+ {
+ size_t selectedFieldIndex = mCurrentAccessChain.getChain().front();
+ mCurrentAccessChain.pop_front(1);
+
+ ASSERT(selectedFieldIndex < node->getChildCount());
+
+ // Visit only said field.
+ node->getChildNode(selectedFieldIndex)->traverse(this);
+ return false;
+ }
+
+ // If this is an array constructor, each element is equally |precise| with the same access
+ // chain. Otherwise there cannot be any access chain for constructors.
+ if (node->getOp() == EOpConstruct)
+ {
+ ASSERT(type.isArray() || mCurrentAccessChain.getChain().empty());
+ return true;
+ }
+
+ // Otherwise this is a function call. The access chain is irrelevant and every (non-out)
+ // parameter of the function call should be considered |precise|.
+ mCurrentAccessChain.clear();
+
+ const TFunction *function = node->getFunction();
+ ASSERT(function);
+
+ for (size_t paramIndex = 0; paramIndex < function->getParamCount(); ++paramIndex)
+ {
+ if (function->getParam(paramIndex)->getType().getQualifier() != EvqParamOut)
+ {
+ node->getChildNode(paramIndex)->traverse(this);
+ }
+ }
+
+ // Mark arithmetic nodes as |precise|.
+ if (IsArithmeticOp(node->getOp()))
+ {
+ node->setIsPrecise();
+ }
+
+ return false;
+ }
+
+ private:
+ ASTInfo *mInfo = nullptr;
+ AccessChain mCurrentAccessChain;
+};
+} // anonymous namespace
+
+void FindPreciseNodes(TCompiler *compiler, TIntermBlock *root)
+{
+ ASTInfo info;
+
+ InfoGatherTraverser infoGather(&info);
+ root->traverse(&infoGather);
+
+ PropagatePreciseTraverser propagator(&info);
+
+ // First, get return expressions out of the way by propagating |precise|.
+ for (TIntermBranch *returnNode : info.preciseReturnNodes)
+ {
+ ASSERT(returnNode->getChildCount() == 1);
+ propagator.propagatePrecise(returnNode->getChildNode(0), {});
+ }
+
+ // Now take |precise| access chains one by one, and propagate their |precise|-ness to the right
+ // hand side of all assignments in which they are on the left hand side, as well as the
+ // arithmetic expression that assigns to them.
+
+ while (!info.preciseObjectsToProcess.empty())
+ {
+ // Get one |precise| object to process.
+ auto first = info.preciseObjectsToProcess.begin();
+ const ObjectAndAccessChain toProcess = *first;
+ info.preciseObjectsToProcess.erase(first);
+
+ // Propagate |precise| to every node where it's assigned to.
+ const TVector<TIntermOperator *> &assignmentNodes =
+ info.variableAssignmentNodeMap[toProcess.variable];
+ for (TIntermOperator *assignmentNode : assignmentNodes)
+ {
+ AccessChain assignmentAccessChain = GetAssignmentAccessChain(assignmentNode);
+
+ // There are two possibilities:
+ //
+ // - The assignment is to a bigger access chain than that which is being processed, in
+ // which case the entire right hand side is marked |precise|,
+ // - The assignment is to a smaller access chain, in which case only the subobject of
+ // the right hand side that corresponds to the remaining part of the access chain must
+ // be marked |precise|.
+ //
+ // For example, if processing |a.b.c| as a |precise| access chain:
+ //
+ // - If the assignment is to |a.b.c.d|, then the entire right hand side must be
+ // |precise|.
+ // - If the assignment is to |a.b|, only the |.c| part of the right hand side expression
+ // must be |precise|.
+ // - If the assignment is to |a.e|, there is nothing to do.
+ //
+ AccessChain remainingAccessChain = toProcess.accessChain;
+ if (!remainingAccessChain.removePrefix(assignmentAccessChain))
+ {
+ continue;
+ }
+
+ propagator.propagatePrecise(assignmentNode, remainingAccessChain);
+ }
+ }
+
+ // The AST nodes now contain information gathered by this post-processing step, and so the tree
+ // must no longer be transformed.
+ compiler->enableValidateNoMoreTransformations();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.h b/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.h
new file mode 100644
index 0000000000..1992ff15af
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2021 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FindPreciseNodes.h: Propagates |precise| to AST nodes. In SPIR-V, the corresponding decoration
+// (NoContraction) is applied on the intermediate result of operations that affect the |precise|
+// variables, not the variables themselves.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_FINDPRECISENODES_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_FINDPRECISENODES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+
+void FindPreciseNodes(TCompiler *compiler, TIntermBlock *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_FINDPRECISENODES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp
new file mode 100644
index 0000000000..2951399390
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp
@@ -0,0 +1,53 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FindSymbol.cpp:
+// Utility for finding a symbol node inside an AST tree.
+
+#include "compiler/translator/tree_util/FindSymbolNode.h"
+
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class SymbolFinder : public TIntermTraverser
+{
+ public:
+ SymbolFinder(const ImmutableString &symbolName)
+ : TIntermTraverser(true, false, false), mSymbolName(symbolName), mNodeFound(nullptr)
+ {}
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (node->variable().symbolType() != SymbolType::Empty && node->getName() == mSymbolName)
+ {
+ mNodeFound = node;
+ }
+ }
+
+ bool isFound() const { return mNodeFound != nullptr; }
+ const TIntermSymbol *getNode() const { return mNodeFound; }
+
+ private:
+ ImmutableString mSymbolName;
+ TIntermSymbol *mNodeFound;
+};
+
+} // anonymous namespace
+
+const TIntermSymbol *FindSymbolNode(TIntermNode *root, const ImmutableString &symbolName)
+{
+ SymbolFinder finder(symbolName);
+ root->traverse(&finder);
+ return finder.getNode();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.h b/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.h
new file mode 100644
index 0000000000..09349484a4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.h
@@ -0,0 +1,23 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FindSymbolNode.h:
+// Utility for finding a symbol node inside an AST tree.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_FINDSYMBOLNODE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_FINDSYMBOLNODE_H_
+
+namespace sh
+{
+
+class ImmutableString;
+class TIntermNode;
+class TIntermSymbol;
+
+const TIntermSymbol *FindSymbolNode(TIntermNode *root, const ImmutableString &symbolName);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_FINDSYMBOLNODE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp
new file mode 100644
index 0000000000..59241bcf7a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp
@@ -0,0 +1,213 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// IntermNodePatternMatcher is a helper class for matching node trees to given patterns.
+// It can be used whenever the same checks for certain node structures are common to multiple AST
+// traversers.
+//
+
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+bool ContainsMatrixNode(const TIntermSequence &sequence)
+{
+ for (size_t ii = 0; ii < sequence.size(); ++ii)
+ {
+ TIntermTyped *node = sequence[ii]->getAsTyped();
+ if (node && node->isMatrix())
+ return true;
+ }
+ return false;
+}
+
+bool ContainsVectorNode(const TIntermSequence &sequence)
+{
+ for (size_t ii = 0; ii < sequence.size(); ++ii)
+ {
+ TIntermTyped *node = sequence[ii]->getAsTyped();
+ if (node && node->isVector())
+ return true;
+ }
+ return false;
+}
+
+} // anonymous namespace
+
+IntermNodePatternMatcher::IntermNodePatternMatcher(const unsigned int mask) : mMask(mask) {}
+
+// static
+bool IntermNodePatternMatcher::IsDynamicIndexingOfNonSSBOVectorOrMatrix(TIntermBinary *node)
+{
+ return IsDynamicIndexingOfVectorOrMatrix(node) && !IsInShaderStorageBlock(node->getLeft());
+}
+
+// static
+bool IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node)
+{
+ return node->getOp() == EOpIndexIndirect && !node->getLeft()->isArray() &&
+ node->getLeft()->getBasicType() != EbtStruct;
+}
+
+// static
+bool IntermNodePatternMatcher::IsDynamicIndexingOfSwizzledVector(TIntermBinary *node)
+{
+ return IsDynamicIndexingOfVectorOrMatrix(node) && node->getLeft()->getAsSwizzleNode();
+}
+
+bool IntermNodePatternMatcher::matchInternal(TIntermBinary *node, TIntermNode *parentNode) const
+{
+ if ((mMask & kExpressionReturningArray) != 0)
+ {
+ if (node->isArray() && node->getOp() == EOpAssign && parentNode != nullptr &&
+ !parentNode->getAsBlock())
+ {
+ return true;
+ }
+ }
+
+ if ((mMask & kUnfoldedShortCircuitExpression) != 0)
+ {
+ if (node->getRight()->hasSideEffects() &&
+ (node->getOp() == EOpLogicalOr || node->getOp() == EOpLogicalAnd))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool IntermNodePatternMatcher::match(TIntermUnary *node) const
+{
+ if ((mMask & kArrayLengthMethod) != 0)
+ {
+ if (node->getOp() == EOpArrayLength)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool IntermNodePatternMatcher::match(TIntermBinary *node, TIntermNode *parentNode) const
+{
+ // L-value tracking information is needed to check for dynamic indexing in L-value.
+ // Traversers that don't track l-values can still use this class and match binary nodes with
+ // this variation of this method if they don't need to check for dynamic indexing in l-values.
+ ASSERT((mMask & kDynamicIndexingOfVectorOrMatrixInLValue) == 0);
+ return matchInternal(node, parentNode);
+}
+
+bool IntermNodePatternMatcher::match(TIntermBinary *node,
+ TIntermNode *parentNode,
+ bool isLValueRequiredHere) const
+{
+ if (matchInternal(node, parentNode))
+ {
+ return true;
+ }
+ if ((mMask & kDynamicIndexingOfVectorOrMatrixInLValue) != 0)
+ {
+ if (isLValueRequiredHere && IsDynamicIndexingOfVectorOrMatrix(node))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool IntermNodePatternMatcher::match(TIntermAggregate *node, TIntermNode *parentNode) const
+{
+ if ((mMask & kExpressionReturningArray) != 0)
+ {
+ if (parentNode != nullptr)
+ {
+ TIntermBinary *parentBinary = parentNode->getAsBinaryNode();
+ bool parentIsAssignment =
+ (parentBinary != nullptr &&
+ (parentBinary->getOp() == EOpAssign || parentBinary->getOp() == EOpInitialize));
+
+ if (node->getType().isArray() && !parentIsAssignment &&
+ (node->isConstructor() || node->isFunctionCall() ||
+ (BuiltInGroup::IsBuiltIn(node->getOp()) &&
+ !BuiltInGroup::IsMath(node->getOp()))) &&
+ !parentNode->getAsBlock())
+ {
+ return true;
+ }
+ }
+ }
+ if ((mMask & kScalarizedVecOrMatConstructor) != 0)
+ {
+ if (node->getOp() == EOpConstruct)
+ {
+ if (node->getType().isVector() && ContainsMatrixNode(*(node->getSequence())))
+ {
+ return true;
+ }
+ else if (node->getType().isMatrix() && ContainsVectorNode(*(node->getSequence())))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool IntermNodePatternMatcher::match(TIntermTernary *node) const
+{
+ if ((mMask & kUnfoldedShortCircuitExpression) != 0)
+ {
+ return true;
+ }
+ return false;
+}
+
+bool IntermNodePatternMatcher::match(TIntermDeclaration *node) const
+{
+ if ((mMask & kMultiDeclaration) != 0)
+ {
+ if (node->getSequence()->size() > 1)
+ {
+ return true;
+ }
+ }
+ if ((mMask & kArrayDeclaration) != 0)
+ {
+ if (node->getSequence()->front()->getAsTyped()->getType().isStructureContainingArrays())
+ {
+ return true;
+ }
+ // Need to check from all declarators whether they are arrays since that may vary between
+ // declarators.
+ for (TIntermNode *declarator : *node->getSequence())
+ {
+ if (declarator->getAsTyped()->isArray())
+ {
+ return true;
+ }
+ }
+ }
+ if ((mMask & kNamelessStructDeclaration) != 0)
+ {
+ TIntermTyped *declarator = node->getSequence()->front()->getAsTyped();
+ if (declarator->getBasicType() == EbtStruct &&
+ declarator->getType().getStruct()->symbolType() == SymbolType::Empty)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.h b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.h
new file mode 100644
index 0000000000..b8321b930c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.h
@@ -0,0 +1,81 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// IntermNodePatternMatcher is a helper class for matching node trees to given patterns.
+// It can be used whenever the same checks for certain node structures are common to multiple AST
+// traversers.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_INTERMNODEPATTERNMATCHER_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_INTERMNODEPATTERNMATCHER_H_
+
+namespace sh
+{
+
+class TIntermAggregate;
+class TIntermBinary;
+class TIntermDeclaration;
+class TIntermNode;
+class TIntermTernary;
+class TIntermUnary;
+
+class IntermNodePatternMatcher
+{
+ public:
+ static bool IsDynamicIndexingOfNonSSBOVectorOrMatrix(TIntermBinary *node);
+ static bool IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node);
+ static bool IsDynamicIndexingOfSwizzledVector(TIntermBinary *node);
+
+ enum PatternType : unsigned int
+ {
+ // Matches expressions that are unfolded to if statements by UnfoldShortCircuitToIf
+ kUnfoldedShortCircuitExpression = 1u << 0u,
+
+ // Matches expressions that return arrays with the exception of simple statements where a
+ // constructor or function call result is assigned.
+ kExpressionReturningArray = 1u << 1u,
+
+ // Matches dynamic indexing of vectors or matrices in l-values.
+ kDynamicIndexingOfVectorOrMatrixInLValue = 1u << 2u,
+
+ // Matches declarations with more than one declared variables.
+ kMultiDeclaration = 1u << 3u,
+
+ // Matches declarations of arrays.
+ kArrayDeclaration = 1u << 4u,
+
+ // Matches declarations of structs where the struct type does not have a name.
+ kNamelessStructDeclaration = 1u << 5u,
+
+ // Matches array length() method.
+ kArrayLengthMethod = 1u << 6u,
+
+ // Matches a vector or matrix constructor whose arguments are scalarized by the
+ // scalarizeVecOrMatConstructorArguments workaround.
+ kScalarizedVecOrMatConstructor = 1u << 7u,
+ };
+ IntermNodePatternMatcher(const unsigned int mask);
+
+ bool match(TIntermUnary *node) const;
+
+ bool match(TIntermBinary *node, TIntermNode *parentNode) const;
+
+ // Use this version for checking binary node matches in case you're using flag
+ // kDynamicIndexingOfVectorOrMatrixInLValue.
+ bool match(TIntermBinary *node, TIntermNode *parentNode, bool isLValueRequiredHere) const;
+
+ bool match(TIntermAggregate *node, TIntermNode *parentNode) const;
+ bool match(TIntermTernary *node) const;
+ bool match(TIntermDeclaration *node) const;
+
+ private:
+ const unsigned int mMask;
+
+ bool matchInternal(TIntermBinary *node, TIntermNode *parentNode) const;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_INTERMNODEPATTERNMATCHER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.cpp
new file mode 100644
index 0000000000..a7bb211425
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.cpp
@@ -0,0 +1,436 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// IntermNode_util.cpp: High-level utilities for creating AST nodes and node hierarchies. Mostly
+// meant to be used in AST transforms.
+
+#include "compiler/translator/tree_util/IntermNode_util.h"
+
+#include "compiler/translator/FunctionLookup.h"
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+namespace
+{
+
+const TFunction *LookUpBuiltInFunction(const char *name,
+ const TIntermSequence *arguments,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ const ImmutableString &mangledName = TFunctionLookup::GetMangledName(name, *arguments);
+ const TSymbol *symbol = symbolTable.findBuiltIn(mangledName, shaderVersion);
+ if (symbol)
+ {
+ ASSERT(symbol->isFunction());
+ return static_cast<const TFunction *>(symbol);
+ }
+ return nullptr;
+}
+
+} // anonymous namespace
+
+TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TFunction &func)
+{
+ return new TIntermFunctionPrototype(&func);
+}
+
+TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TFunction &func,
+ TIntermBlock *functionBody)
+{
+ return new TIntermFunctionDefinition(new TIntermFunctionPrototype(&func), functionBody);
+}
+
+TIntermTyped *CreateZeroNode(const TType &type)
+{
+ TType constType(type);
+ constType.setQualifier(EvqConst);
+
+ if (!type.isArray() && type.getBasicType() != EbtStruct)
+ {
+ size_t size = constType.getObjectSize();
+ TConstantUnion *u = new TConstantUnion[size];
+ for (size_t i = 0; i < size; ++i)
+ {
+ switch (type.getBasicType())
+ {
+ case EbtFloat:
+ u[i].setFConst(0.0f);
+ break;
+ case EbtInt:
+ u[i].setIConst(0);
+ break;
+ case EbtUInt:
+ u[i].setUConst(0u);
+ break;
+ case EbtBool:
+ u[i].setBConst(false);
+ break;
+ default:
+ // CreateZeroNode is called by ParseContext that keeps parsing even when an
+ // error occurs, so it is possible for CreateZeroNode to be called with
+ // non-basic types. This happens only on error condition but CreateZeroNode
+ // needs to return a value with the correct type to continue the type check.
+ // That's why we handle non-basic type by setting whatever value, we just need
+ // the type to be right.
+ u[i].setIConst(42);
+ break;
+ }
+ }
+
+ TIntermConstantUnion *node = new TIntermConstantUnion(u, constType);
+ return node;
+ }
+
+ TIntermSequence arguments;
+
+ if (type.isArray())
+ {
+ TType elementType(type);
+ elementType.toArrayElementType();
+
+ size_t arraySize = type.getOutermostArraySize();
+ for (size_t i = 0; i < arraySize; ++i)
+ {
+ arguments.push_back(CreateZeroNode(elementType));
+ }
+ }
+ else
+ {
+ ASSERT(type.getBasicType() == EbtStruct);
+
+ const TStructure *structure = type.getStruct();
+ for (const auto &field : structure->fields())
+ {
+ arguments.push_back(CreateZeroNode(*field->type()));
+ }
+ }
+
+ return TIntermAggregate::CreateConstructor(constType, &arguments);
+}
+
+TIntermConstantUnion *CreateFloatNode(float value, TPrecision precision)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setFConst(value);
+
+ TType type(EbtFloat, precision, EvqConst, 1);
+ return new TIntermConstantUnion(u, type);
+}
+
+TIntermConstantUnion *CreateVecNode(const float values[],
+ unsigned int vecSize,
+ TPrecision precision)
+{
+ TConstantUnion *u = new TConstantUnion[vecSize];
+ for (unsigned int channel = 0; channel < vecSize; ++channel)
+ {
+ u[channel].setFConst(values[channel]);
+ }
+
+ TType type(EbtFloat, precision, EvqConst, static_cast<uint8_t>(vecSize));
+ return new TIntermConstantUnion(u, type);
+}
+
+TIntermConstantUnion *CreateUVecNode(const unsigned int values[],
+ unsigned int vecSize,
+ TPrecision precision)
+{
+ TConstantUnion *u = new TConstantUnion[vecSize];
+ for (unsigned int channel = 0; channel < vecSize; ++channel)
+ {
+ u[channel].setUConst(values[channel]);
+ }
+
+ TType type(EbtUInt, precision, EvqConst, static_cast<uint8_t>(vecSize));
+ return new TIntermConstantUnion(u, type);
+}
+
+TIntermConstantUnion *CreateIndexNode(int index)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setIConst(index);
+
+ TType type(EbtInt, EbpHigh, EvqConst, 1);
+ return new TIntermConstantUnion(u, type);
+}
+
+TIntermConstantUnion *CreateUIntNode(unsigned int value)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setUConst(value);
+
+ TType type(EbtUInt, EbpHigh, EvqConst, 1);
+ return new TIntermConstantUnion(u, type);
+}
+
+TIntermConstantUnion *CreateBoolNode(bool value)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setBConst(value);
+
+ TType type(EbtBool, EbpUndefined, EvqConst, 1);
+ return new TIntermConstantUnion(u, type);
+}
+
+TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type)
+{
+ ASSERT(symbolTable != nullptr);
+ // TODO(oetuaho): Might be useful to sanitize layout qualifier etc. on the type of the created
+ // variable. This might need to be done in other places as well.
+ return new TVariable(symbolTable, kEmptyImmutableString, type, SymbolType::AngleInternal);
+}
+
+TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type, TQualifier qualifier)
+{
+ ASSERT(symbolTable != nullptr);
+ if (type->getQualifier() == qualifier)
+ {
+ return CreateTempVariable(symbolTable, type);
+ }
+ TType *typeWithQualifier = new TType(*type);
+ typeWithQualifier->setQualifier(qualifier);
+ return CreateTempVariable(symbolTable, typeWithQualifier);
+}
+
+TIntermSymbol *CreateTempSymbolNode(const TVariable *tempVariable)
+{
+ ASSERT(tempVariable->symbolType() == SymbolType::AngleInternal);
+ ASSERT(tempVariable->getType().getQualifier() == EvqTemporary ||
+ tempVariable->getType().getQualifier() == EvqConst ||
+ tempVariable->getType().getQualifier() == EvqGlobal);
+ return new TIntermSymbol(tempVariable);
+}
+
+TIntermDeclaration *CreateTempDeclarationNode(const TVariable *tempVariable)
+{
+ TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
+ tempDeclaration->appendDeclarator(CreateTempSymbolNode(tempVariable));
+ return tempDeclaration;
+}
+
+TIntermDeclaration *CreateTempInitDeclarationNode(const TVariable *tempVariable,
+ TIntermTyped *initializer)
+{
+ ASSERT(initializer != nullptr);
+ TIntermSymbol *tempSymbol = CreateTempSymbolNode(tempVariable);
+ TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
+ TIntermBinary *tempInit = new TIntermBinary(EOpInitialize, tempSymbol, initializer);
+ tempDeclaration->appendDeclarator(tempInit);
+ return tempDeclaration;
+}
+
+TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTyped *rightNode)
+{
+ ASSERT(rightNode != nullptr);
+ TIntermSymbol *tempSymbol = CreateTempSymbolNode(tempVariable);
+ return new TIntermBinary(EOpAssign, tempSymbol, rightNode);
+}
+
+TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
+ const TType *type,
+ TQualifier qualifier,
+ TIntermDeclaration **declarationOut)
+{
+ TVariable *variable = CreateTempVariable(symbolTable, type, qualifier);
+ *declarationOut = CreateTempDeclarationNode(variable);
+ return variable;
+}
+
+TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
+ TIntermTyped *initializer,
+ TQualifier qualifier,
+ TIntermDeclaration **declarationOut)
+{
+ TVariable *variable =
+ CreateTempVariable(symbolTable, new TType(initializer->getType()), qualifier);
+ *declarationOut = CreateTempInitDeclarationNode(variable, initializer);
+ return variable;
+}
+
+std::pair<const TVariable *, const TVariable *> DeclareStructure(
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ TFieldList *fieldList,
+ TQualifier qualifier,
+ const TMemoryQualifier &memoryQualifier,
+ uint32_t arraySize,
+ const ImmutableString &structTypeName,
+ const ImmutableString *structInstanceName)
+{
+ TStructure *structure =
+ new TStructure(symbolTable, structTypeName, fieldList, SymbolType::AngleInternal);
+
+ auto makeStructureType = [&](bool isStructSpecifier) {
+ TType *structureType = new TType(structure, isStructSpecifier);
+ structureType->setQualifier(qualifier);
+ structureType->setMemoryQualifier(memoryQualifier);
+ if (arraySize > 0)
+ {
+ structureType->makeArray(arraySize);
+ }
+ return structureType;
+ };
+
+ TIntermSequence insertSequence;
+
+ TVariable *typeVar = new TVariable(symbolTable, kEmptyImmutableString, makeStructureType(true),
+ SymbolType::Empty);
+ insertSequence.push_back(new TIntermDeclaration{typeVar});
+
+ TVariable *instanceVar = nullptr;
+ if (structInstanceName)
+ {
+ instanceVar = new TVariable(symbolTable, *structInstanceName, makeStructureType(false),
+ SymbolType::AngleInternal);
+ insertSequence.push_back(new TIntermDeclaration{instanceVar});
+ }
+
+ size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(root);
+ root->insertChildNodes(firstFunctionIndex, insertSequence);
+
+ return {typeVar, instanceVar};
+}
+
+const TVariable *DeclareInterfaceBlock(TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ TFieldList *fieldList,
+ TQualifier qualifier,
+ const TLayoutQualifier &layoutQualifier,
+ const TMemoryQualifier &memoryQualifier,
+ uint32_t arraySize,
+ const ImmutableString &blockTypeName,
+ const ImmutableString &blockVariableName)
+{
+ // Define an interface block.
+ TInterfaceBlock *interfaceBlock = new TInterfaceBlock(
+ symbolTable, blockTypeName, fieldList, layoutQualifier, SymbolType::AngleInternal);
+
+ // Turn the inteface block into a declaration.
+ TType *interfaceBlockType = new TType(interfaceBlock, qualifier, layoutQualifier);
+ interfaceBlockType->setMemoryQualifier(memoryQualifier);
+ if (arraySize > 0)
+ {
+ interfaceBlockType->makeArray(arraySize);
+ }
+
+ TIntermDeclaration *interfaceBlockDecl = new TIntermDeclaration;
+ TVariable *interfaceBlockVar =
+ new TVariable(symbolTable, blockVariableName, interfaceBlockType,
+ blockVariableName.empty() ? SymbolType::Empty : SymbolType::AngleInternal);
+ TIntermSymbol *interfaceBlockDeclarator = new TIntermSymbol(interfaceBlockVar);
+ interfaceBlockDecl->appendDeclarator(interfaceBlockDeclarator);
+
+ // Insert the declarations before the first function.
+ TIntermSequence insertSequence;
+ insertSequence.push_back(interfaceBlockDecl);
+
+ size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(root);
+ root->insertChildNodes(firstFunctionIndex, insertSequence);
+
+ return interfaceBlockVar;
+}
+
+TIntermBlock *EnsureBlock(TIntermNode *node)
+{
+ if (node == nullptr)
+ return nullptr;
+ TIntermBlock *blockNode = node->getAsBlock();
+ if (blockNode != nullptr)
+ return blockNode;
+
+ blockNode = new TIntermBlock();
+ blockNode->setLine(node->getLine());
+ blockNode->appendStatement(node);
+ return blockNode;
+}
+
+TIntermSymbol *ReferenceGlobalVariable(const ImmutableString &name, const TSymbolTable &symbolTable)
+{
+ const TSymbol *symbol = symbolTable.findGlobal(name);
+ ASSERT(symbol && symbol->isVariable());
+ return new TIntermSymbol(static_cast<const TVariable *>(symbol));
+}
+
+TIntermSymbol *ReferenceBuiltInVariable(const ImmutableString &name,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ const TVariable *var =
+ static_cast<const TVariable *>(symbolTable.findBuiltIn(name, shaderVersion));
+ ASSERT(var);
+ return new TIntermSymbol(var);
+}
+
+TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
+ TIntermSequence *arguments,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ const TFunction *fn = LookUpBuiltInFunction(name, arguments, symbolTable, shaderVersion);
+ ASSERT(fn);
+ TOperator op = fn->getBuiltInOp();
+ if (BuiltInGroup::IsMath(op) && arguments->size() == 1)
+ {
+ return new TIntermUnary(op, arguments->at(0)->getAsTyped(), fn);
+ }
+ return TIntermAggregate::CreateBuiltInFunctionCall(*fn, arguments);
+}
+
+TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
+ const std::initializer_list<TIntermNode *> &arguments,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ TIntermSequence argSequence(arguments);
+ return CreateBuiltInFunctionCallNode(name, &argSequence, symbolTable, shaderVersion);
+}
+
+TIntermTyped *CreateBuiltInUnaryFunctionCallNode(const char *name,
+ TIntermTyped *argument,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ return CreateBuiltInFunctionCallNode(name, {argument}, symbolTable, shaderVersion);
+}
+
+int GetESSLOrGLSLVersion(ShShaderSpec spec, int esslVersion, int glslVersion)
+{
+ return IsDesktopGLSpec(spec) ? glslVersion : esslVersion;
+}
+
+// Returns true if a block ends in a branch (break, continue, return, etc). This is only correct
+// after PruneNoOps, because it expects empty blocks after a branch to have been already pruned,
+// i.e. a block can only end in a branch if its last statement is a branch or is a block ending in
+// branch.
+bool EndsInBranch(TIntermBlock *block)
+{
+ while (block != nullptr)
+ {
+ // Get the last statement of the block.
+ TIntermSequence &statements = *block->getSequence();
+ if (statements.empty())
+ {
+ return false;
+ }
+
+ TIntermNode *lastStatement = statements.back();
+
+ // If it's a branch itself, we have the answer.
+ if (lastStatement->getAsBranchNode())
+ {
+ return true;
+ }
+
+ // Otherwise, see if it's a block that ends in a branch
+ block = lastStatement->getAsBlock();
+ }
+
+ return false;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.h b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.h
new file mode 100644
index 0000000000..5cf0a117d3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.h
@@ -0,0 +1,128 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// IntermNode_util.h: High-level utilities for creating AST nodes and node hierarchies. Mostly meant
+// to be used in AST transforms.
+
+#ifndef COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
+#define COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/FindFunction.h"
+
+namespace sh
+{
+
+class TSymbolTable;
+class TVariable;
+
+TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TFunction &func);
+TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TFunction &func,
+ TIntermBlock *functionBody);
+
+TIntermTyped *CreateZeroNode(const TType &type);
+TIntermConstantUnion *CreateFloatNode(float value, TPrecision precision);
+TIntermConstantUnion *CreateVecNode(const float values[],
+ unsigned int vecSize,
+ TPrecision precision);
+TIntermConstantUnion *CreateUVecNode(const unsigned int values[],
+ unsigned int vecSize,
+ TPrecision precision);
+TIntermConstantUnion *CreateIndexNode(int index);
+TIntermConstantUnion *CreateUIntNode(unsigned int value);
+TIntermConstantUnion *CreateBoolNode(bool value);
+
+TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type);
+TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type, TQualifier qualifier);
+
+TIntermSymbol *CreateTempSymbolNode(const TVariable *tempVariable);
+TIntermDeclaration *CreateTempDeclarationNode(const TVariable *tempVariable);
+TIntermDeclaration *CreateTempInitDeclarationNode(const TVariable *tempVariable,
+ TIntermTyped *initializer);
+TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTyped *rightNode);
+
+TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
+ const TType *type,
+ TQualifier qualifier,
+ TIntermDeclaration **declarationOut);
+TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
+ TIntermTyped *initializer,
+ TQualifier qualifier,
+ TIntermDeclaration **declarationOut);
+std::pair<const TVariable *, const TVariable *> DeclareStructure(
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ TFieldList *fieldList,
+ TQualifier qualifier,
+ const TMemoryQualifier &memoryQualifier,
+ uint32_t arraySize,
+ const ImmutableString &structTypeName,
+ const ImmutableString *structInstanceName);
+const TVariable *DeclareInterfaceBlock(TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ TFieldList *fieldList,
+ TQualifier qualifier,
+ const TLayoutQualifier &layoutQualifier,
+ const TMemoryQualifier &memoryQualifier,
+ uint32_t arraySize,
+ const ImmutableString &blockTypeName,
+ const ImmutableString &blockVariableName);
+
+// If the input node is nullptr, return nullptr.
+// If the input node is a block node, return it.
+// If the input node is not a block node, put it inside a block node and return that.
+TIntermBlock *EnsureBlock(TIntermNode *node);
+
+// Should be called from inside Compiler::compileTreeImpl() where the global level is in scope.
+TIntermSymbol *ReferenceGlobalVariable(const ImmutableString &name,
+ const TSymbolTable &symbolTable);
+
+// Note: this can't access desktop GLSL built-ins. Those can only be accessed directly through
+// BuiltIn.h.
+TIntermSymbol *ReferenceBuiltInVariable(const ImmutableString &name,
+ const TSymbolTable &symbolTable,
+ int shaderVersion);
+
+TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
+ TIntermSequence *arguments,
+ const TSymbolTable &symbolTable,
+ int shaderVersion);
+TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
+ const std::initializer_list<TIntermNode *> &arguments,
+ const TSymbolTable &symbolTable,
+ int shaderVersion);
+TIntermTyped *CreateBuiltInUnaryFunctionCallNode(const char *name,
+ TIntermTyped *argument,
+ const TSymbolTable &symbolTable,
+ int shaderVersion);
+
+int GetESSLOrGLSLVersion(ShShaderSpec spec, int esslVersion, int glslVersion);
+
+inline void GetSwizzleIndex(TVector<int> *indexOut) {}
+
+template <typename T, typename... ArgsT>
+void GetSwizzleIndex(TVector<int> *indexOut, T arg, ArgsT... args)
+{
+ indexOut->push_back(arg);
+ GetSwizzleIndex(indexOut, args...);
+}
+
+template <typename... ArgsT>
+TIntermSwizzle *CreateSwizzle(TIntermTyped *reference, ArgsT... args)
+{
+ TVector<int> swizzleIndex;
+ GetSwizzleIndex(&swizzleIndex, args...);
+ return new TIntermSwizzle(reference, swizzleIndex);
+}
+
+// Returns true if a block ends in a branch (break, continue, return, etc). This is only correct
+// after PruneNoOps, because it expects empty blocks after a branch to have been already pruned,
+// i.e. a block can only end in a branch if its last statement is a branch or is a block ending in
+// branch.
+bool EndsInBranch(TIntermBlock *block);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.cpp
new file mode 100644
index 0000000000..667535fa63
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.cpp
@@ -0,0 +1,1046 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include <algorithm>
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/AsNode.h"
+#include "compiler/translator/tree_util/IntermRebuild.h"
+
+#define GUARD2(cond, failVal) \
+ do \
+ { \
+ if (!(cond)) \
+ { \
+ return failVal; \
+ } \
+ } while (false)
+
+#define GUARD(cond) GUARD2(cond, nullptr)
+
+namespace sh
+{
+
+template <typename T, typename U>
+ANGLE_INLINE bool AllBits(T haystack, U needle)
+{
+ return (haystack & needle) == needle;
+}
+
+template <typename T, typename U>
+ANGLE_INLINE bool AnyBits(T haystack, U needle)
+{
+ return (haystack & needle) != 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TIntermRebuild::BaseResult::BaseResult(BaseResult &other)
+ : mAction(other.mAction),
+ mVisit(other.mVisit),
+ mSingle(other.mSingle),
+ mMulti(std::move(other.mMulti))
+{}
+
+TIntermRebuild::BaseResult::BaseResult(TIntermNode &node, VisitBits visit)
+ : mAction(Action::ReplaceSingle), mVisit(visit), mSingle(&node)
+{}
+
+TIntermRebuild::BaseResult::BaseResult(TIntermNode *node, VisitBits visit)
+ : mAction(node ? Action::ReplaceSingle : Action::Drop),
+ mVisit(node ? visit : VisitBits::Neither),
+ mSingle(node)
+{}
+
+TIntermRebuild::BaseResult::BaseResult(std::nullptr_t)
+ : mAction(Action::Drop), mVisit(VisitBits::Neither), mSingle(nullptr)
+{}
+
+TIntermRebuild::BaseResult::BaseResult(Fail)
+ : mAction(Action::Fail), mVisit(VisitBits::Neither), mSingle(nullptr)
+{}
+
+TIntermRebuild::BaseResult::BaseResult(std::vector<TIntermNode *> &&nodes)
+ : mAction(Action::ReplaceMulti),
+ mVisit(VisitBits::Neither),
+ mSingle(nullptr),
+ mMulti(std::move(nodes))
+{}
+
+void TIntermRebuild::BaseResult::moveAssignImpl(BaseResult &other)
+{
+ mAction = other.mAction;
+ mVisit = other.mVisit;
+ mSingle = other.mSingle;
+ mMulti = std::move(other.mMulti);
+}
+
+TIntermRebuild::BaseResult TIntermRebuild::BaseResult::Multi(std::vector<TIntermNode *> &&nodes)
+{
+ auto it = std::remove(nodes.begin(), nodes.end(), nullptr);
+ nodes.erase(it, nodes.end());
+ return std::move(nodes);
+}
+
+bool TIntermRebuild::BaseResult::isFail() const
+{
+ return mAction == Action::Fail;
+}
+
+bool TIntermRebuild::BaseResult::isDrop() const
+{
+ return mAction == Action::Drop;
+}
+
+TIntermNode *TIntermRebuild::BaseResult::single() const
+{
+ return mSingle;
+}
+
+const std::vector<TIntermNode *> *TIntermRebuild::BaseResult::multi() const
+{
+ if (mAction == Action::ReplaceMulti)
+ {
+ return &mMulti;
+ }
+ return nullptr;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+using PreResult = TIntermRebuild::PreResult;
+
+PreResult::PreResult(TIntermNode &node, VisitBits visit) : BaseResult(node, visit) {}
+PreResult::PreResult(TIntermNode *node, VisitBits visit) : BaseResult(node, visit) {}
+PreResult::PreResult(std::nullptr_t) : BaseResult(nullptr) {}
+PreResult::PreResult(Fail) : BaseResult(Fail()) {}
+
+PreResult::PreResult(BaseResult &&other) : BaseResult(other) {}
+PreResult::PreResult(PreResult &&other) : BaseResult(other) {}
+
+void PreResult::operator=(PreResult &&other)
+{
+ moveAssignImpl(other);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+using PostResult = TIntermRebuild::PostResult;
+
+PostResult::PostResult(TIntermNode &node) : BaseResult(node, VisitBits::Neither) {}
+PostResult::PostResult(TIntermNode *node) : BaseResult(node, VisitBits::Neither) {}
+PostResult::PostResult(std::nullptr_t) : BaseResult(nullptr) {}
+PostResult::PostResult(Fail) : BaseResult(Fail()) {}
+
+PostResult::PostResult(PostResult &&other) : BaseResult(other) {}
+PostResult::PostResult(BaseResult &&other) : BaseResult(other) {}
+
+void PostResult::operator=(PostResult &&other)
+{
+ moveAssignImpl(other);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TIntermRebuild::TIntermRebuild(TCompiler &compiler, bool preVisit, bool postVisit)
+ : mCompiler(compiler),
+ mSymbolTable(compiler.getSymbolTable()),
+ mPreVisit(preVisit),
+ mPostVisit(postVisit)
+{
+ ASSERT(preVisit || postVisit);
+}
+
+TIntermRebuild::~TIntermRebuild()
+{
+ ASSERT(!mNodeStack.value);
+ ASSERT(!mNodeStack.tail);
+}
+
+const TFunction *TIntermRebuild::getParentFunction() const
+{
+ return mParentFunc;
+}
+
+TIntermNode *TIntermRebuild::getParentNode(size_t offset) const
+{
+ ASSERT(mNodeStack.tail);
+ auto parent = *mNodeStack.tail;
+ while (offset > 0)
+ {
+ --offset;
+ ASSERT(parent.tail);
+ parent = *parent.tail;
+ }
+ return parent.value;
+}
+
+bool TIntermRebuild::rebuildRoot(TIntermBlock &root)
+{
+ if (!rebuildInPlace(root))
+ {
+ return false;
+ }
+ return mCompiler.validateAST(&root);
+}
+
+bool TIntermRebuild::rebuildInPlace(TIntermAggregate &node)
+{
+ return rebuildInPlaceImpl(node);
+}
+
+bool TIntermRebuild::rebuildInPlace(TIntermBlock &node)
+{
+ return rebuildInPlaceImpl(node);
+}
+
+bool TIntermRebuild::rebuildInPlace(TIntermDeclaration &node)
+{
+ return rebuildInPlaceImpl(node);
+}
+
+template <typename Node>
+bool TIntermRebuild::rebuildInPlaceImpl(Node &node)
+{
+ auto *newNode = traverseAnyAs<Node>(node);
+ if (!newNode)
+ {
+ return false;
+ }
+
+ if (newNode != &node)
+ {
+ *node.getSequence() = std::move(*newNode->getSequence());
+ }
+
+ return true;
+}
+
+PostResult TIntermRebuild::rebuild(TIntermNode &node)
+{
+ return traverseAny(node);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <typename Node>
+Node *TIntermRebuild::traverseAnyAs(TIntermNode &node)
+{
+ PostResult result(traverseAny(node));
+ if (result.mAction == Action::Fail || !result.mSingle)
+ {
+ return nullptr;
+ }
+ return asNode<Node>(result.mSingle);
+}
+
+template <typename Node>
+bool TIntermRebuild::traverseAnyAs(TIntermNode &node, Node *&out)
+{
+ PostResult result(traverseAny(node));
+ if (result.mAction == Action::Fail || result.mAction == Action::ReplaceMulti)
+ {
+ return false;
+ }
+ if (!result.mSingle)
+ {
+ return true;
+ }
+ out = asNode<Node>(result.mSingle);
+ return out != nullptr;
+}
+
+bool TIntermRebuild::traverseAggregateBaseChildren(TIntermAggregateBase &node)
+{
+ auto *const children = node.getSequence();
+ ASSERT(children);
+ TIntermSequence newChildren;
+
+ for (TIntermNode *child : *children)
+ {
+ ASSERT(child);
+ PostResult result(traverseAny(*child));
+
+ switch (result.mAction)
+ {
+ case Action::ReplaceSingle:
+ newChildren.push_back(result.mSingle);
+ break;
+
+ case Action::ReplaceMulti:
+ for (TIntermNode *newNode : result.mMulti)
+ {
+ if (newNode)
+ {
+ newChildren.push_back(newNode);
+ }
+ }
+ break;
+
+ case Action::Drop:
+ break;
+
+ case Action::Fail:
+ return false;
+
+ default:
+ ASSERT(false);
+ return false;
+ }
+ }
+
+ *children = std::move(newChildren);
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct TIntermRebuild::NodeStackGuard
+{
+ ConsList<TIntermNode *> oldNodeStack;
+ ConsList<TIntermNode *> &nodeStack;
+ NodeStackGuard(ConsList<TIntermNode *> &nodeStack, TIntermNode *node)
+ : oldNodeStack(nodeStack), nodeStack(nodeStack)
+ {
+ nodeStack = {node, &oldNodeStack};
+ }
+ ~NodeStackGuard() { nodeStack = oldNodeStack; }
+};
+
+PostResult TIntermRebuild::traverseAny(TIntermNode &originalNode)
+{
+ PreResult preResult = traversePre(originalNode);
+ if (!preResult.mSingle)
+ {
+ ASSERT(preResult.mVisit == VisitBits::Neither);
+ return std::move(preResult);
+ }
+
+ TIntermNode *currNode = preResult.mSingle;
+ const VisitBits visit = preResult.mVisit;
+ const NodeType currNodeType = getNodeType(*currNode);
+
+ currNode = traverseChildren(currNodeType, originalNode, *currNode, visit);
+ if (!currNode)
+ {
+ return Fail();
+ }
+
+ return traversePost(currNodeType, originalNode, *currNode, visit);
+}
+
+PreResult TIntermRebuild::traversePre(TIntermNode &originalNode)
+{
+ if (!mPreVisit)
+ {
+ return {originalNode, VisitBits::Both};
+ }
+
+ NodeStackGuard guard(mNodeStack, &originalNode);
+
+ const NodeType originalNodeType = getNodeType(originalNode);
+
+ switch (originalNodeType)
+ {
+ case NodeType::Unknown:
+ ASSERT(false);
+ return Fail();
+ case NodeType::Symbol:
+ return visitSymbolPre(*originalNode.getAsSymbolNode());
+ case NodeType::ConstantUnion:
+ return visitConstantUnionPre(*originalNode.getAsConstantUnion());
+ case NodeType::FunctionPrototype:
+ return visitFunctionPrototypePre(*originalNode.getAsFunctionPrototypeNode());
+ case NodeType::PreprocessorDirective:
+ return visitPreprocessorDirectivePre(*originalNode.getAsPreprocessorDirective());
+ case NodeType::Unary:
+ return visitUnaryPre(*originalNode.getAsUnaryNode());
+ case NodeType::Binary:
+ return visitBinaryPre(*originalNode.getAsBinaryNode());
+ case NodeType::Ternary:
+ return visitTernaryPre(*originalNode.getAsTernaryNode());
+ case NodeType::Swizzle:
+ return visitSwizzlePre(*originalNode.getAsSwizzleNode());
+ case NodeType::IfElse:
+ return visitIfElsePre(*originalNode.getAsIfElseNode());
+ case NodeType::Switch:
+ return visitSwitchPre(*originalNode.getAsSwitchNode());
+ case NodeType::Case:
+ return visitCasePre(*originalNode.getAsCaseNode());
+ case NodeType::FunctionDefinition:
+ return visitFunctionDefinitionPre(*originalNode.getAsFunctionDefinition());
+ case NodeType::Aggregate:
+ return visitAggregatePre(*originalNode.getAsAggregate());
+ case NodeType::Block:
+ return visitBlockPre(*originalNode.getAsBlock());
+ case NodeType::GlobalQualifierDeclaration:
+ return visitGlobalQualifierDeclarationPre(
+ *originalNode.getAsGlobalQualifierDeclarationNode());
+ case NodeType::Declaration:
+ return visitDeclarationPre(*originalNode.getAsDeclarationNode());
+ case NodeType::Loop:
+ return visitLoopPre(*originalNode.getAsLoopNode());
+ case NodeType::Branch:
+ return visitBranchPre(*originalNode.getAsBranchNode());
+ default:
+ ASSERT(false);
+ return Fail();
+ }
+}
+
+TIntermNode *TIntermRebuild::traverseChildren(NodeType currNodeType,
+ const TIntermNode &originalNode,
+ TIntermNode &currNode,
+ VisitBits visit)
+{
+ if (!AnyBits(visit, VisitBits::Children))
+ {
+ return &currNode;
+ }
+
+ if (AnyBits(visit, VisitBits::ChildrenRequiresSame) && &originalNode != &currNode)
+ {
+ return &currNode;
+ }
+
+ NodeStackGuard guard(mNodeStack, &currNode);
+
+ switch (currNodeType)
+ {
+ case NodeType::Unknown:
+ ASSERT(false);
+ return nullptr;
+ case NodeType::Symbol:
+ return &currNode;
+ case NodeType::ConstantUnion:
+ return &currNode;
+ case NodeType::FunctionPrototype:
+ return &currNode;
+ case NodeType::PreprocessorDirective:
+ return &currNode;
+ case NodeType::Unary:
+ return traverseUnaryChildren(*currNode.getAsUnaryNode());
+ case NodeType::Binary:
+ return traverseBinaryChildren(*currNode.getAsBinaryNode());
+ case NodeType::Ternary:
+ return traverseTernaryChildren(*currNode.getAsTernaryNode());
+ case NodeType::Swizzle:
+ return traverseSwizzleChildren(*currNode.getAsSwizzleNode());
+ case NodeType::IfElse:
+ return traverseIfElseChildren(*currNode.getAsIfElseNode());
+ case NodeType::Switch:
+ return traverseSwitchChildren(*currNode.getAsSwitchNode());
+ case NodeType::Case:
+ return traverseCaseChildren(*currNode.getAsCaseNode());
+ case NodeType::FunctionDefinition:
+ return traverseFunctionDefinitionChildren(*currNode.getAsFunctionDefinition());
+ case NodeType::Aggregate:
+ return traverseAggregateChildren(*currNode.getAsAggregate());
+ case NodeType::Block:
+ return traverseBlockChildren(*currNode.getAsBlock());
+ case NodeType::GlobalQualifierDeclaration:
+ return traverseGlobalQualifierDeclarationChildren(
+ *currNode.getAsGlobalQualifierDeclarationNode());
+ case NodeType::Declaration:
+ return traverseDeclarationChildren(*currNode.getAsDeclarationNode());
+ case NodeType::Loop:
+ return traverseLoopChildren(*currNode.getAsLoopNode());
+ case NodeType::Branch:
+ return traverseBranchChildren(*currNode.getAsBranchNode());
+ default:
+ ASSERT(false);
+ return nullptr;
+ }
+}
+
+PostResult TIntermRebuild::traversePost(NodeType currNodeType,
+ const TIntermNode &originalNode,
+ TIntermNode &currNode,
+ VisitBits visit)
+{
+ if (!mPostVisit)
+ {
+ return currNode;
+ }
+
+ if (!AnyBits(visit, VisitBits::Post))
+ {
+ return currNode;
+ }
+
+ if (AnyBits(visit, VisitBits::PostRequiresSame) && &originalNode != &currNode)
+ {
+ return currNode;
+ }
+
+ NodeStackGuard guard(mNodeStack, &currNode);
+
+ switch (currNodeType)
+ {
+ case NodeType::Unknown:
+ ASSERT(false);
+ return Fail();
+ case NodeType::Symbol:
+ return visitSymbolPost(*currNode.getAsSymbolNode());
+ case NodeType::ConstantUnion:
+ return visitConstantUnionPost(*currNode.getAsConstantUnion());
+ case NodeType::FunctionPrototype:
+ return visitFunctionPrototypePost(*currNode.getAsFunctionPrototypeNode());
+ case NodeType::PreprocessorDirective:
+ return visitPreprocessorDirectivePost(*currNode.getAsPreprocessorDirective());
+ case NodeType::Unary:
+ return visitUnaryPost(*currNode.getAsUnaryNode());
+ case NodeType::Binary:
+ return visitBinaryPost(*currNode.getAsBinaryNode());
+ case NodeType::Ternary:
+ return visitTernaryPost(*currNode.getAsTernaryNode());
+ case NodeType::Swizzle:
+ return visitSwizzlePost(*currNode.getAsSwizzleNode());
+ case NodeType::IfElse:
+ return visitIfElsePost(*currNode.getAsIfElseNode());
+ case NodeType::Switch:
+ return visitSwitchPost(*currNode.getAsSwitchNode());
+ case NodeType::Case:
+ return visitCasePost(*currNode.getAsCaseNode());
+ case NodeType::FunctionDefinition:
+ return visitFunctionDefinitionPost(*currNode.getAsFunctionDefinition());
+ case NodeType::Aggregate:
+ return visitAggregatePost(*currNode.getAsAggregate());
+ case NodeType::Block:
+ return visitBlockPost(*currNode.getAsBlock());
+ case NodeType::GlobalQualifierDeclaration:
+ return visitGlobalQualifierDeclarationPost(
+ *currNode.getAsGlobalQualifierDeclarationNode());
+ case NodeType::Declaration:
+ return visitDeclarationPost(*currNode.getAsDeclarationNode());
+ case NodeType::Loop:
+ return visitLoopPost(*currNode.getAsLoopNode());
+ case NodeType::Branch:
+ return visitBranchPost(*currNode.getAsBranchNode());
+ default:
+ ASSERT(false);
+ return Fail();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TIntermNode *TIntermRebuild::traverseAggregateChildren(TIntermAggregate &node)
+{
+ if (traverseAggregateBaseChildren(node))
+ {
+ return &node;
+ }
+ return nullptr;
+}
+
+TIntermNode *TIntermRebuild::traverseBlockChildren(TIntermBlock &node)
+{
+ if (traverseAggregateBaseChildren(node))
+ {
+ return &node;
+ }
+ return nullptr;
+}
+
+TIntermNode *TIntermRebuild::traverseDeclarationChildren(TIntermDeclaration &node)
+{
+ if (traverseAggregateBaseChildren(node))
+ {
+ return &node;
+ }
+ return nullptr;
+}
+
+TIntermNode *TIntermRebuild::traverseSwizzleChildren(TIntermSwizzle &node)
+{
+ auto *const operand = node.getOperand();
+ ASSERT(operand);
+
+ auto *newOperand = traverseAnyAs<TIntermTyped>(*operand);
+ GUARD(newOperand);
+
+ if (newOperand != operand)
+ {
+ return new TIntermSwizzle(newOperand, node.getSwizzleOffsets());
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseBinaryChildren(TIntermBinary &node)
+{
+ auto *const left = node.getLeft();
+ ASSERT(left);
+ auto *const right = node.getRight();
+ ASSERT(right);
+
+ auto *const newLeft = traverseAnyAs<TIntermTyped>(*left);
+ GUARD(newLeft);
+ auto *const newRight = traverseAnyAs<TIntermTyped>(*right);
+ GUARD(newRight);
+
+ if (newLeft != left || newRight != right)
+ {
+ TOperator op = node.getOp();
+ switch (op)
+ {
+ case TOperator::EOpIndexDirectStruct:
+ {
+ if (newLeft->getType().getInterfaceBlock())
+ {
+ op = TOperator::EOpIndexDirectInterfaceBlock;
+ }
+ }
+ break;
+
+ case TOperator::EOpIndexDirectInterfaceBlock:
+ {
+ if (newLeft->getType().getStruct())
+ {
+ op = TOperator::EOpIndexDirectStruct;
+ }
+ }
+ break;
+
+ case TOperator::EOpComma:
+ return TIntermBinary::CreateComma(newLeft, newRight, mCompiler.getShaderVersion());
+
+ default:
+ break;
+ }
+
+ return new TIntermBinary(op, newLeft, newRight);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseUnaryChildren(TIntermUnary &node)
+{
+ auto *const operand = node.getOperand();
+ ASSERT(operand);
+
+ auto *const newOperand = traverseAnyAs<TIntermTyped>(*operand);
+ GUARD(newOperand);
+
+ if (newOperand != operand)
+ {
+ return new TIntermUnary(node.getOp(), newOperand, node.getFunction());
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseTernaryChildren(TIntermTernary &node)
+{
+ auto *const cond = node.getCondition();
+ ASSERT(cond);
+ auto *const true_ = node.getTrueExpression();
+ ASSERT(true_);
+ auto *const false_ = node.getFalseExpression();
+ ASSERT(false_);
+
+ auto *const newCond = traverseAnyAs<TIntermTyped>(*cond);
+ GUARD(newCond);
+ auto *const newTrue = traverseAnyAs<TIntermTyped>(*true_);
+ GUARD(newTrue);
+ auto *const newFalse = traverseAnyAs<TIntermTyped>(*false_);
+ GUARD(newFalse);
+
+ if (newCond != cond || newTrue != true_ || newFalse != false_)
+ {
+ return new TIntermTernary(newCond, newTrue, newFalse);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseIfElseChildren(TIntermIfElse &node)
+{
+ auto *const cond = node.getCondition();
+ ASSERT(cond);
+ auto *const true_ = node.getTrueBlock();
+ auto *const false_ = node.getFalseBlock();
+
+ auto *const newCond = traverseAnyAs<TIntermTyped>(*cond);
+ GUARD(newCond);
+ TIntermBlock *newTrue = nullptr;
+ if (true_)
+ {
+ GUARD(traverseAnyAs(*true_, newTrue));
+ }
+ TIntermBlock *newFalse = nullptr;
+ if (false_)
+ {
+ GUARD(traverseAnyAs(*false_, newFalse));
+ }
+
+ if (newCond != cond || newTrue != true_ || newFalse != false_)
+ {
+ return new TIntermIfElse(newCond, newTrue, newFalse);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseSwitchChildren(TIntermSwitch &node)
+{
+ auto *const init = node.getInit();
+ ASSERT(init);
+ auto *const stmts = node.getStatementList();
+ ASSERT(stmts);
+
+ auto *const newInit = traverseAnyAs<TIntermTyped>(*init);
+ GUARD(newInit);
+ auto *const newStmts = traverseAnyAs<TIntermBlock>(*stmts);
+ GUARD(newStmts);
+
+ if (newInit != init || newStmts != stmts)
+ {
+ return new TIntermSwitch(newInit, newStmts);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseCaseChildren(TIntermCase &node)
+{
+ auto *const cond = node.getCondition();
+
+ TIntermTyped *newCond = nullptr;
+ if (cond)
+ {
+ GUARD(traverseAnyAs(*cond, newCond));
+ }
+
+ if (newCond != cond)
+ {
+ return new TIntermCase(newCond);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseFunctionDefinitionChildren(TIntermFunctionDefinition &node)
+{
+ GUARD(!mParentFunc); // Function definitions cannot be nested.
+ mParentFunc = node.getFunction();
+ struct OnExit
+ {
+ const TFunction *&parentFunc;
+ OnExit(const TFunction *&parentFunc) : parentFunc(parentFunc) {}
+ ~OnExit() { parentFunc = nullptr; }
+ } onExit(mParentFunc);
+
+ auto *const proto = node.getFunctionPrototype();
+ ASSERT(proto);
+ auto *const body = node.getBody();
+ ASSERT(body);
+
+ auto *const newProto = traverseAnyAs<TIntermFunctionPrototype>(*proto);
+ GUARD(newProto);
+ auto *const newBody = traverseAnyAs<TIntermBlock>(*body);
+ GUARD(newBody);
+
+ if (newProto != proto || newBody != body)
+ {
+ return new TIntermFunctionDefinition(newProto, newBody);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseGlobalQualifierDeclarationChildren(
+ TIntermGlobalQualifierDeclaration &node)
+{
+ auto *const symbol = node.getSymbol();
+ ASSERT(symbol);
+
+ auto *const newSymbol = traverseAnyAs<TIntermSymbol>(*symbol);
+ GUARD(newSymbol);
+
+ if (newSymbol != symbol)
+ {
+ return new TIntermGlobalQualifierDeclaration(newSymbol, node.isPrecise(), node.getLine());
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseLoopChildren(TIntermLoop &node)
+{
+ const TLoopType loopType = node.getType();
+
+ auto *const init = node.getInit();
+ auto *const cond = node.getCondition();
+ auto *const expr = node.getExpression();
+ auto *const body = node.getBody();
+ ASSERT(body);
+
+#if defined(ANGLE_ENABLE_ASSERTS)
+ switch (loopType)
+ {
+ case TLoopType::ELoopFor:
+ break;
+ case TLoopType::ELoopWhile:
+ case TLoopType::ELoopDoWhile:
+ ASSERT(cond);
+ ASSERT(!init && !expr);
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+#endif
+
+ auto *const newBody = traverseAnyAs<TIntermBlock>(*body);
+ GUARD(newBody);
+ TIntermNode *newInit = nullptr;
+ if (init)
+ {
+ GUARD(traverseAnyAs(*init, newInit));
+ }
+ TIntermTyped *newCond = nullptr;
+ if (cond)
+ {
+ GUARD(traverseAnyAs(*cond, newCond));
+ }
+ TIntermTyped *newExpr = nullptr;
+ if (expr)
+ {
+ GUARD(traverseAnyAs(*expr, newExpr));
+ }
+
+ if (newInit != init || newCond != cond || newExpr != expr || newBody != body)
+ {
+ switch (loopType)
+ {
+ case TLoopType::ELoopFor:
+ GUARD(newBody);
+ break;
+ case TLoopType::ELoopWhile:
+ case TLoopType::ELoopDoWhile:
+ GUARD(newCond && newBody);
+ GUARD(!newInit && !newExpr);
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+ return new TIntermLoop(loopType, newInit, newCond, newExpr, newBody);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseBranchChildren(TIntermBranch &node)
+{
+ auto *const expr = node.getExpression();
+
+ TIntermTyped *newExpr = nullptr;
+ if (expr)
+ {
+ GUARD(traverseAnyAs<TIntermTyped>(*expr, newExpr));
+ }
+
+ if (newExpr != expr)
+ {
+ return new TIntermBranch(node.getFlowOp(), newExpr);
+ }
+
+ return &node;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+PreResult TIntermRebuild::visitSymbolPre(TIntermSymbol &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitConstantUnionPre(TIntermConstantUnion &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitFunctionPrototypePre(TIntermFunctionPrototype &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitPreprocessorDirectivePre(TIntermPreprocessorDirective &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitUnaryPre(TIntermUnary &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitBinaryPre(TIntermBinary &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitTernaryPre(TIntermTernary &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitSwizzlePre(TIntermSwizzle &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitIfElsePre(TIntermIfElse &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitSwitchPre(TIntermSwitch &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitCasePre(TIntermCase &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitLoopPre(TIntermLoop &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitBranchPre(TIntermBranch &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitDeclarationPre(TIntermDeclaration &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitBlockPre(TIntermBlock &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitAggregatePre(TIntermAggregate &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitFunctionDefinitionPre(TIntermFunctionDefinition &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitGlobalQualifierDeclarationPre(
+ TIntermGlobalQualifierDeclaration &node)
+{
+ return {node, VisitBits::Both};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+PostResult TIntermRebuild::visitSymbolPost(TIntermSymbol &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitConstantUnionPost(TIntermConstantUnion &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitFunctionPrototypePost(TIntermFunctionPrototype &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitPreprocessorDirectivePost(TIntermPreprocessorDirective &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitUnaryPost(TIntermUnary &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitBinaryPost(TIntermBinary &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitTernaryPost(TIntermTernary &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitSwizzlePost(TIntermSwizzle &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitIfElsePost(TIntermIfElse &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitSwitchPost(TIntermSwitch &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitCasePost(TIntermCase &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitLoopPost(TIntermLoop &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitBranchPost(TIntermBranch &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitDeclarationPost(TIntermDeclaration &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitBlockPost(TIntermBlock &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitAggregatePost(TIntermAggregate &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitFunctionDefinitionPost(TIntermFunctionDefinition &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitGlobalQualifierDeclarationPost(
+ TIntermGlobalQualifierDeclaration &node)
+{
+ return node;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.h b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.h
new file mode 100644
index 0000000000..7907d283ef
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.h
@@ -0,0 +1,328 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_INTERMREBUILD_H_
+#define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_INTERMREBUILD_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/NodeType.h"
+
+namespace sh
+{
+
+// Walks the tree to rebuild nodes.
+// This class is intended to be derived with overridden visitXXX functions.
+//
+// Each visitXXX function that does not have a Visit parameter simply has the visitor called
+// exactly once, regardless of (preVisit) or (postVisit) values.
+
+// Each visitXXX function that has a Visit parameter behaves as follows:
+// * If (preVisit):
+// - The node is visited before children are traversed.
+// - The returned value is used to replace the visited node. The returned value may be the same
+// as the original node.
+// - If multiple nodes are returned, children and post visits of the returned nodes are not
+// preformed, even if it is a singleton collection.
+// * If (childVisit)
+// - If any new children are returned, the node is automatically rebuilt with the new children
+// before post visit.
+// - Depending on the type of the node, null children may be discarded.
+// - Ill-typed children cause rebuild errors. Ill-typed means the node to automatically rebuild
+// cannot accept a child of a certain type as input to its constructor.
+// - Only instances of TIntermAggregateBase can accept Multi results for any of its children.
+// If supplied, the nodes are spliced children at the spot of the original child.
+// * If (postVisit)
+// - The node is visited after any children are traversed.
+// - Only after such a rebuild (or lack thereof), the post-visit is performed.
+//
+// Nodes in visit functions are allowed to be modified in place, including TIntermAggregateBase
+// child sequences.
+//
+// The default implementations of all the visitXXX functions support full pre and post traversal
+// without modifying the visited nodes.
+//
+class TIntermRebuild : angle::NonCopyable
+{
+
+ enum class Action
+ {
+ ReplaceSingle,
+ ReplaceMulti,
+ Drop,
+ Fail,
+ };
+
+ public:
+ struct Fail
+ {};
+
+ enum VisitBits : size_t
+ {
+ // No bits are set.
+ Empty = 0u,
+
+ // Allow visit of returned node's children.
+ Children = 1u << 0u,
+
+ // Allow post visit of returned node.
+ Post = 1u << 1u,
+
+ // If (Children) bit, only visit if the returned node is the same as the original node.
+ ChildrenRequiresSame = 1u << 2u,
+
+ // If (Post) bit, only visit if the returned node is the same as the original node.
+ PostRequiresSame = 1u << 3u,
+
+ RequireSame = ChildrenRequiresSame | PostRequiresSame,
+ Neither = Empty,
+ Both = Children | Post,
+ BothWhenSame = Both | RequireSame,
+ };
+
+ private:
+ struct NodeStackGuard;
+
+ template <typename T>
+ struct ConsList
+ {
+ T value;
+ ConsList<T> *tail;
+ };
+
+ class BaseResult
+ {
+ BaseResult(const BaseResult &) = delete;
+ BaseResult &operator=(const BaseResult &) = delete;
+
+ public:
+ BaseResult(BaseResult &&other) = default;
+ BaseResult(BaseResult &other); // For subclass move constructor impls
+ BaseResult(TIntermNode &node, VisitBits visit);
+ BaseResult(TIntermNode *node, VisitBits visit);
+ BaseResult(std::nullptr_t);
+ BaseResult(Fail);
+ BaseResult(std::vector<TIntermNode *> &&nodes);
+
+ void moveAssignImpl(BaseResult &other); // For subclass move assign impls
+
+ static BaseResult Multi(std::vector<TIntermNode *> &&nodes);
+
+ template <typename Iter>
+ static BaseResult Multi(Iter nodesBegin, Iter nodesEnd)
+ {
+ std::vector<TIntermNode *> nodes;
+ for (Iter nodesCurr = nodesBegin; nodesCurr != nodesEnd; ++nodesCurr)
+ {
+ nodes.push_back(*nodesCurr);
+ }
+ return std::move(nodes);
+ }
+
+ bool isFail() const;
+ bool isDrop() const;
+ TIntermNode *single() const;
+ const std::vector<TIntermNode *> *multi() const;
+
+ public:
+ Action mAction;
+ VisitBits mVisit;
+ TIntermNode *mSingle;
+ std::vector<TIntermNode *> mMulti;
+ };
+
+ public:
+ class PreResult : private BaseResult
+ {
+ friend class TIntermRebuild;
+
+ public:
+ PreResult(PreResult &&other);
+ PreResult(TIntermNode &node, VisitBits visit = VisitBits::BothWhenSame);
+ PreResult(TIntermNode *node, VisitBits visit = VisitBits::BothWhenSame);
+ PreResult(std::nullptr_t); // Used to drop a node.
+ PreResult(Fail); // Used to signal failure.
+
+ void operator=(PreResult &&other);
+
+ static PreResult Multi(std::vector<TIntermNode *> &&nodes)
+ {
+ return BaseResult::Multi(std::move(nodes));
+ }
+
+ template <typename Iter>
+ static PreResult Multi(Iter nodesBegin, Iter nodesEnd)
+ {
+ return BaseResult::Multi(nodesBegin, nodesEnd);
+ }
+
+ using BaseResult::isDrop;
+ using BaseResult::isFail;
+ using BaseResult::multi;
+ using BaseResult::single;
+
+ private:
+ PreResult(BaseResult &&other);
+ };
+
+ class PostResult : private BaseResult
+ {
+ friend class TIntermRebuild;
+
+ public:
+ PostResult(PostResult &&other);
+ PostResult(TIntermNode &node);
+ PostResult(TIntermNode *node);
+ PostResult(std::nullptr_t); // Used to drop a node
+ PostResult(Fail); // Used to signal failure.
+
+ void operator=(PostResult &&other);
+
+ static PostResult Multi(std::vector<TIntermNode *> &&nodes)
+ {
+ return BaseResult::Multi(std::move(nodes));
+ }
+
+ template <typename Iter>
+ static PostResult Multi(Iter nodesBegin, Iter nodesEnd)
+ {
+ return BaseResult::Multi(nodesBegin, nodesEnd);
+ }
+
+ using BaseResult::isDrop;
+ using BaseResult::isFail;
+ using BaseResult::multi;
+ using BaseResult::single;
+
+ private:
+ PostResult(BaseResult &&other);
+ };
+
+ public:
+ TIntermRebuild(TCompiler &compiler, bool preVisit, bool postVisit);
+
+ virtual ~TIntermRebuild();
+
+ // Rebuilds the tree starting at the provided root. If a new node would be returned for the
+ // root, the root node's children become that of the new node instead. Returns false if failure
+ // occurred.
+ [[nodiscard]] bool rebuildRoot(TIntermBlock &root);
+
+ protected:
+ virtual PreResult visitSymbolPre(TIntermSymbol &node);
+ virtual PreResult visitConstantUnionPre(TIntermConstantUnion &node);
+ virtual PreResult visitFunctionPrototypePre(TIntermFunctionPrototype &node);
+ virtual PreResult visitPreprocessorDirectivePre(TIntermPreprocessorDirective &node);
+ virtual PreResult visitUnaryPre(TIntermUnary &node);
+ virtual PreResult visitBinaryPre(TIntermBinary &node);
+ virtual PreResult visitTernaryPre(TIntermTernary &node);
+ virtual PreResult visitSwizzlePre(TIntermSwizzle &node);
+ virtual PreResult visitIfElsePre(TIntermIfElse &node);
+ virtual PreResult visitSwitchPre(TIntermSwitch &node);
+ virtual PreResult visitCasePre(TIntermCase &node);
+ virtual PreResult visitLoopPre(TIntermLoop &node);
+ virtual PreResult visitBranchPre(TIntermBranch &node);
+ virtual PreResult visitDeclarationPre(TIntermDeclaration &node);
+ virtual PreResult visitBlockPre(TIntermBlock &node);
+ virtual PreResult visitAggregatePre(TIntermAggregate &node);
+ virtual PreResult visitFunctionDefinitionPre(TIntermFunctionDefinition &node);
+ virtual PreResult visitGlobalQualifierDeclarationPre(TIntermGlobalQualifierDeclaration &node);
+
+ virtual PostResult visitSymbolPost(TIntermSymbol &node);
+ virtual PostResult visitConstantUnionPost(TIntermConstantUnion &node);
+ virtual PostResult visitFunctionPrototypePost(TIntermFunctionPrototype &node);
+ virtual PostResult visitPreprocessorDirectivePost(TIntermPreprocessorDirective &node);
+ virtual PostResult visitUnaryPost(TIntermUnary &node);
+ virtual PostResult visitBinaryPost(TIntermBinary &node);
+ virtual PostResult visitTernaryPost(TIntermTernary &node);
+ virtual PostResult visitSwizzlePost(TIntermSwizzle &node);
+ virtual PostResult visitIfElsePost(TIntermIfElse &node);
+ virtual PostResult visitSwitchPost(TIntermSwitch &node);
+ virtual PostResult visitCasePost(TIntermCase &node);
+ virtual PostResult visitLoopPost(TIntermLoop &node);
+ virtual PostResult visitBranchPost(TIntermBranch &node);
+ virtual PostResult visitDeclarationPost(TIntermDeclaration &node);
+ virtual PostResult visitBlockPost(TIntermBlock &node);
+ virtual PostResult visitAggregatePost(TIntermAggregate &node);
+ virtual PostResult visitFunctionDefinitionPost(TIntermFunctionDefinition &node);
+ virtual PostResult visitGlobalQualifierDeclarationPost(TIntermGlobalQualifierDeclaration &node);
+
+ // Can be used to rebuild a specific node during a traversal. Useful for fine control of
+ // rebuilding a node's children.
+ [[nodiscard]] PostResult rebuild(TIntermNode &node);
+
+ // Rebuilds the provided node in place. If a new node would be returned, the old node's children
+ // become that of the new node instead. Returns false if failure occurred.
+ [[nodiscard]] bool rebuildInPlace(TIntermAggregate &node);
+
+ // Rebuilds the provided node in place. If a new node would be returned, the old node's children
+ // become that of the new node instead. Returns false if failure occurred.
+ [[nodiscard]] bool rebuildInPlace(TIntermBlock &node);
+
+ // Rebuilds the provided node in place. If a new node would be returned, the old node's children
+ // become that of the new node instead. Returns false if failure occurred.
+ [[nodiscard]] bool rebuildInPlace(TIntermDeclaration &node);
+
+ // If currently at or below a function declaration body, this returns the function that encloses
+ // the currently visited node. (This returns null if at a function declaration node.)
+ const TFunction *getParentFunction() const;
+
+ TIntermNode *getParentNode(size_t offset = 0) const;
+
+ private:
+ template <typename Node>
+ [[nodiscard]] bool rebuildInPlaceImpl(Node &node);
+
+ PostResult traverseAny(TIntermNode &node);
+
+ template <typename Node>
+ Node *traverseAnyAs(TIntermNode &node);
+
+ template <typename Node>
+ bool traverseAnyAs(TIntermNode &node, Node *&out);
+
+ PreResult traversePre(TIntermNode &originalNode);
+ TIntermNode *traverseChildren(NodeType currNodeType,
+ const TIntermNode &originalNode,
+ TIntermNode &currNode,
+ VisitBits visit);
+ PostResult traversePost(NodeType nodeType,
+ const TIntermNode &originalNode,
+ TIntermNode &currNode,
+ VisitBits visit);
+
+ bool traverseAggregateBaseChildren(TIntermAggregateBase &node);
+
+ TIntermNode *traverseUnaryChildren(TIntermUnary &node);
+ TIntermNode *traverseBinaryChildren(TIntermBinary &node);
+ TIntermNode *traverseTernaryChildren(TIntermTernary &node);
+ TIntermNode *traverseSwizzleChildren(TIntermSwizzle &node);
+ TIntermNode *traverseIfElseChildren(TIntermIfElse &node);
+ TIntermNode *traverseSwitchChildren(TIntermSwitch &node);
+ TIntermNode *traverseCaseChildren(TIntermCase &node);
+ TIntermNode *traverseLoopChildren(TIntermLoop &node);
+ TIntermNode *traverseBranchChildren(TIntermBranch &node);
+ TIntermNode *traverseDeclarationChildren(TIntermDeclaration &node);
+ TIntermNode *traverseBlockChildren(TIntermBlock &node);
+ TIntermNode *traverseAggregateChildren(TIntermAggregate &node);
+ TIntermNode *traverseFunctionDefinitionChildren(TIntermFunctionDefinition &node);
+ TIntermNode *traverseGlobalQualifierDeclarationChildren(
+ TIntermGlobalQualifierDeclaration &node);
+
+ protected:
+ TCompiler &mCompiler;
+ TSymbolTable &mSymbolTable;
+ const TFunction *mParentFunc = nullptr;
+ GetNodeType getNodeType;
+
+ private:
+ ConsList<TIntermNode *> mNodeStack{nullptr, nullptr};
+ bool mPreVisit;
+ bool mPostVisit;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_INTERMREBUILD_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.cpp
new file mode 100644
index 0000000000..c4bbe1fa4d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.cpp
@@ -0,0 +1,708 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+// Traverse the intermediate representation tree, and call a node type specific visit function for
+// each node. Traversal is done recursively through the node member function traverse(). Nodes with
+// children can have their whole subtree skipped if preVisit is turned on and the type specific
+// function returns false.
+template <typename T>
+void TIntermTraverser::traverse(T *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ bool visit = true;
+
+ // Visit the node before children if pre-visiting.
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ if (visit)
+ {
+ size_t childIndex = 0;
+ size_t childCount = node->getChildCount();
+
+ while (childIndex < childCount && visit)
+ {
+ mCurrentChildIndex = childIndex;
+ node->getChildNode(childIndex)->traverse(this);
+ mCurrentChildIndex = childIndex;
+
+ if (inVisit && childIndex != childCount - 1)
+ {
+ visit = node->visit(InVisit, this);
+ }
+ ++childIndex;
+ }
+
+ if (visit && postVisit)
+ node->visit(PostVisit, this);
+ }
+}
+
+// Instantiate template for RewriteAtomicFunctionExpressions, in case this gets inlined thus not
+// exported from the TU.
+template void TIntermTraverser::traverse(TIntermNode *);
+
+void TIntermNode::traverse(TIntermTraverser *it)
+{
+ it->traverse(this);
+}
+
+void TIntermSymbol::traverse(TIntermTraverser *it)
+{
+ TIntermTraverser::ScopedNodeInTraversalPath addToPath(it, this);
+ it->visitSymbol(this);
+}
+
+void TIntermConstantUnion::traverse(TIntermTraverser *it)
+{
+ TIntermTraverser::ScopedNodeInTraversalPath addToPath(it, this);
+ it->visitConstantUnion(this);
+}
+
+void TIntermFunctionPrototype::traverse(TIntermTraverser *it)
+{
+ TIntermTraverser::ScopedNodeInTraversalPath addToPath(it, this);
+ it->visitFunctionPrototype(this);
+}
+
+void TIntermBinary::traverse(TIntermTraverser *it)
+{
+ it->traverseBinary(this);
+}
+
+void TIntermUnary::traverse(TIntermTraverser *it)
+{
+ it->traverseUnary(this);
+}
+
+void TIntermFunctionDefinition::traverse(TIntermTraverser *it)
+{
+ it->traverseFunctionDefinition(this);
+}
+
+void TIntermBlock::traverse(TIntermTraverser *it)
+{
+ it->traverseBlock(this);
+}
+
+void TIntermAggregate::traverse(TIntermTraverser *it)
+{
+ it->traverseAggregate(this);
+}
+
+void TIntermLoop::traverse(TIntermTraverser *it)
+{
+ it->traverseLoop(this);
+}
+
+void TIntermPreprocessorDirective::traverse(TIntermTraverser *it)
+{
+ it->visitPreprocessorDirective(this);
+}
+
+bool TIntermSymbol::visit(Visit visit, TIntermTraverser *it)
+{
+ it->visitSymbol(this);
+ return false;
+}
+
+bool TIntermConstantUnion::visit(Visit visit, TIntermTraverser *it)
+{
+ it->visitConstantUnion(this);
+ return false;
+}
+
+bool TIntermFunctionPrototype::visit(Visit visit, TIntermTraverser *it)
+{
+ it->visitFunctionPrototype(this);
+ return false;
+}
+
+bool TIntermFunctionDefinition::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitFunctionDefinition(visit, this);
+}
+
+bool TIntermUnary::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitUnary(visit, this);
+}
+
+bool TIntermSwizzle::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitSwizzle(visit, this);
+}
+
+bool TIntermBinary::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitBinary(visit, this);
+}
+
+bool TIntermTernary::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitTernary(visit, this);
+}
+
+bool TIntermAggregate::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitAggregate(visit, this);
+}
+
+bool TIntermDeclaration::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitDeclaration(visit, this);
+}
+
+bool TIntermGlobalQualifierDeclaration::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitGlobalQualifierDeclaration(visit, this);
+}
+
+bool TIntermBlock::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitBlock(visit, this);
+}
+
+bool TIntermIfElse::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitIfElse(visit, this);
+}
+
+bool TIntermLoop::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitLoop(visit, this);
+}
+
+bool TIntermBranch::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitBranch(visit, this);
+}
+
+bool TIntermSwitch::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitSwitch(visit, this);
+}
+
+bool TIntermCase::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitCase(visit, this);
+}
+
+bool TIntermPreprocessorDirective::visit(Visit visit, TIntermTraverser *it)
+{
+ it->visitPreprocessorDirective(this);
+ return false;
+}
+
+TIntermTraverser::TIntermTraverser(bool preVisit,
+ bool inVisit,
+ bool postVisit,
+ TSymbolTable *symbolTable)
+ : preVisit(preVisit),
+ inVisit(inVisit),
+ postVisit(postVisit),
+ mMaxDepth(0),
+ mMaxAllowedDepth(std::numeric_limits<int>::max()),
+ mInGlobalScope(true),
+ mSymbolTable(symbolTable),
+ mCurrentChildIndex(0)
+{
+ // Only enabling inVisit is not supported.
+ ASSERT(!(inVisit && !preVisit && !postVisit));
+}
+
+TIntermTraverser::~TIntermTraverser() {}
+
+void TIntermTraverser::setMaxAllowedDepth(int depth)
+{
+ mMaxAllowedDepth = depth;
+}
+
+const TIntermBlock *TIntermTraverser::getParentBlock() const
+{
+ if (!mParentBlockStack.empty())
+ {
+ return mParentBlockStack.back().node;
+ }
+ return nullptr;
+}
+
+void TIntermTraverser::pushParentBlock(TIntermBlock *node)
+{
+ mParentBlockStack.push_back(ParentBlock(node, 0));
+}
+
+void TIntermTraverser::incrementParentBlockPos()
+{
+ ++mParentBlockStack.back().pos;
+}
+
+void TIntermTraverser::popParentBlock()
+{
+ ASSERT(!mParentBlockStack.empty());
+ mParentBlockStack.pop_back();
+}
+
+void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &insertions)
+{
+ TIntermSequence emptyInsertionsAfter;
+ insertStatementsInParentBlock(insertions, emptyInsertionsAfter);
+}
+
+void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &insertionsBefore,
+ const TIntermSequence &insertionsAfter)
+{
+ ASSERT(!mParentBlockStack.empty());
+ ParentBlock &parentBlock = mParentBlockStack.back();
+ if (mPath.back() == parentBlock.node)
+ {
+ ASSERT(mParentBlockStack.size() >= 2u);
+ // The current node is a block node, so the parent block is not the topmost one in the block
+ // stack, but the one below that.
+ parentBlock = mParentBlockStack.at(mParentBlockStack.size() - 2u);
+ }
+ NodeInsertMultipleEntry insert(parentBlock.node, parentBlock.pos, insertionsBefore,
+ insertionsAfter);
+ mInsertions.push_back(insert);
+}
+
+void TIntermTraverser::insertStatementInParentBlock(TIntermNode *statement)
+{
+ TIntermSequence insertions;
+ insertions.push_back(statement);
+ insertStatementsInParentBlock(insertions);
+}
+
+void TIntermTraverser::insertStatementsInBlockAtPosition(TIntermBlock *parent,
+ size_t position,
+ const TIntermSequence &insertionsBefore,
+ const TIntermSequence &insertionsAfter)
+{
+ ASSERT(parent);
+ ASSERT(position >= 0);
+ ASSERT(position < parent->getChildCount());
+
+ mInsertions.emplace_back(parent, position, insertionsBefore, insertionsAfter);
+}
+
+void TLValueTrackingTraverser::setInFunctionCallOutParameter(bool inOutParameter)
+{
+ mInFunctionCallOutParameter = inOutParameter;
+}
+
+bool TLValueTrackingTraverser::isInFunctionCallOutParameter() const
+{
+ return mInFunctionCallOutParameter;
+}
+
+void TIntermTraverser::traverseBinary(TIntermBinary *node)
+{
+ traverse(node);
+}
+
+void TLValueTrackingTraverser::traverseBinary(TIntermBinary *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ bool visit = true;
+
+ // visit the node before children if pre-visiting.
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ // Visit the children, in the right order.
+ if (visit)
+ {
+ if (node->isAssignment())
+ {
+ ASSERT(!isLValueRequiredHere());
+ setOperatorRequiresLValue(true);
+ }
+
+ node->getLeft()->traverse(this);
+
+ if (node->isAssignment())
+ setOperatorRequiresLValue(false);
+
+ if (inVisit)
+ visit = node->visit(InVisit, this);
+
+ if (visit)
+ {
+ // Some binary operations like indexing can be inside an expression which must be an
+ // l-value.
+ bool parentOperatorRequiresLValue = operatorRequiresLValue();
+ bool parentInFunctionCallOutParameter = isInFunctionCallOutParameter();
+
+ // Index is not required to be an l-value even when the surrounding expression is
+ // required to be an l-value.
+ TOperator op = node->getOp();
+ if (op == EOpIndexDirect || op == EOpIndexDirectInterfaceBlock ||
+ op == EOpIndexDirectStruct || op == EOpIndexIndirect)
+ {
+ setOperatorRequiresLValue(false);
+ setInFunctionCallOutParameter(false);
+ }
+
+ node->getRight()->traverse(this);
+
+ setOperatorRequiresLValue(parentOperatorRequiresLValue);
+ setInFunctionCallOutParameter(parentInFunctionCallOutParameter);
+
+ // Visit the node after the children, if requested and the traversal
+ // hasn't been cancelled yet.
+ if (postVisit)
+ visit = node->visit(PostVisit, this);
+ }
+ }
+}
+
+void TIntermTraverser::traverseUnary(TIntermUnary *node)
+{
+ traverse(node);
+}
+
+void TLValueTrackingTraverser::traverseUnary(TIntermUnary *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ bool visit = true;
+
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ if (visit)
+ {
+ ASSERT(!operatorRequiresLValue());
+ switch (node->getOp())
+ {
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+ setOperatorRequiresLValue(true);
+ break;
+ default:
+ break;
+ }
+
+ node->getOperand()->traverse(this);
+
+ setOperatorRequiresLValue(false);
+
+ if (postVisit)
+ visit = node->visit(PostVisit, this);
+ }
+}
+
+// Traverse a function definition node. This keeps track of global scope.
+void TIntermTraverser::traverseFunctionDefinition(TIntermFunctionDefinition *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ bool visit = true;
+
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ if (visit)
+ {
+ mCurrentChildIndex = 0;
+ node->getFunctionPrototype()->traverse(this);
+ mCurrentChildIndex = 0;
+
+ if (inVisit)
+ visit = node->visit(InVisit, this);
+ if (visit)
+ {
+ mInGlobalScope = false;
+ mCurrentChildIndex = 1;
+ node->getBody()->traverse(this);
+ mCurrentChildIndex = 1;
+ mInGlobalScope = true;
+ if (postVisit)
+ visit = node->visit(PostVisit, this);
+ }
+ }
+}
+
+// Traverse a block node. This keeps track of the position of traversed child nodes within the block
+// so that nodes may be inserted before or after them.
+void TIntermTraverser::traverseBlock(TIntermBlock *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ pushParentBlock(node);
+
+ bool visit = true;
+
+ TIntermSequence *sequence = node->getSequence();
+
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ if (visit)
+ {
+ for (size_t childIndex = 0; childIndex < sequence->size(); ++childIndex)
+ {
+ TIntermNode *child = (*sequence)[childIndex];
+ if (visit)
+ {
+ mCurrentChildIndex = childIndex;
+ child->traverse(this);
+ mCurrentChildIndex = childIndex;
+
+ if (inVisit)
+ {
+ if (child != sequence->back())
+ visit = node->visit(InVisit, this);
+ }
+
+ incrementParentBlockPos();
+ }
+ }
+
+ if (visit && postVisit)
+ visit = node->visit(PostVisit, this);
+ }
+
+ popParentBlock();
+}
+
+void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
+{
+ traverse(node);
+}
+
+bool TIntermTraverser::CompareInsertion(const NodeInsertMultipleEntry &a,
+ const NodeInsertMultipleEntry &b)
+{
+ if (a.parent != b.parent)
+ {
+ return a.parent < b.parent;
+ }
+ return a.position < b.position;
+}
+
+bool TIntermTraverser::updateTree(TCompiler *compiler, TIntermNode *node)
+{
+ // Sort the insertions so that insertion position is increasing and same position insertions are
+ // not reordered. The insertions are processed in reverse order so that multiple insertions to
+ // the same parent node are handled correctly.
+ std::stable_sort(mInsertions.begin(), mInsertions.end(), CompareInsertion);
+ for (size_t ii = 0; ii < mInsertions.size(); ++ii)
+ {
+ // If two insertions are to the same position, insert them in the order they were specified.
+ // The std::stable_sort call above will automatically guarantee this.
+ const NodeInsertMultipleEntry &insertion = mInsertions[mInsertions.size() - ii - 1];
+ ASSERT(insertion.parent);
+ if (!insertion.insertionsAfter.empty())
+ {
+ bool inserted = insertion.parent->insertChildNodes(insertion.position + 1,
+ insertion.insertionsAfter);
+ ASSERT(inserted);
+ }
+ if (!insertion.insertionsBefore.empty())
+ {
+ bool inserted =
+ insertion.parent->insertChildNodes(insertion.position, insertion.insertionsBefore);
+ ASSERT(inserted);
+ }
+ }
+ for (size_t ii = 0; ii < mReplacements.size(); ++ii)
+ {
+ const NodeUpdateEntry &replacement = mReplacements[ii];
+ ASSERT(replacement.parent);
+ bool replaced =
+ replacement.parent->replaceChildNode(replacement.original, replacement.replacement);
+ ASSERT(replaced);
+
+ // Make sure the precision is not accidentally dropped. It's ok if the precision is not the
+ // same, as the transformations are allowed to replace an expression with one that is
+ // temporarily evaluated at a different (likely higher) precision.
+ TIntermTyped *originalAsTyped = replacement.original->getAsTyped();
+ TIntermTyped *replacementAsTyped =
+ replacement.replacement ? replacement.replacement->getAsTyped() : nullptr;
+ if (originalAsTyped != nullptr && replacementAsTyped != nullptr)
+ {
+ const TType &originalType = originalAsTyped->getType();
+ const TType &replacementType = replacementAsTyped->getType();
+ ASSERT(!IsPrecisionApplicableToType(originalType.getBasicType()) ||
+ !IsPrecisionApplicableToType(replacementType.getBasicType()) ||
+ originalType.getPrecision() == EbpUndefined ||
+ replacementType.getPrecision() != EbpUndefined);
+ }
+
+ if (!replacement.originalBecomesChildOfReplacement)
+ {
+ // In AST traversing, a parent is visited before its children.
+ // After we replace a node, if its immediate child is to
+ // be replaced, we need to make sure we don't update the replaced
+ // node; instead, we update the replacement node.
+ for (size_t jj = ii + 1; jj < mReplacements.size(); ++jj)
+ {
+ NodeUpdateEntry &replacement2 = mReplacements[jj];
+ if (replacement2.parent == replacement.original)
+ replacement2.parent = replacement.replacement;
+ }
+ }
+ }
+ for (size_t ii = 0; ii < mMultiReplacements.size(); ++ii)
+ {
+ const NodeReplaceWithMultipleEntry &replacement = mMultiReplacements[ii];
+ ASSERT(replacement.parent);
+ bool replaced = replacement.parent->replaceChildNodeWithMultiple(replacement.original,
+ replacement.replacements);
+ ASSERT(replaced);
+ }
+
+ clearReplacementQueue();
+
+ return compiler->validateAST(node);
+}
+
+void TIntermTraverser::clearReplacementQueue()
+{
+ mReplacements.clear();
+ mMultiReplacements.clear();
+ mInsertions.clear();
+}
+
+void TIntermTraverser::queueReplacement(TIntermNode *replacement, OriginalNode originalStatus)
+{
+ queueReplacementWithParent(getParentNode(), mPath.back(), replacement, originalStatus);
+}
+
+void TIntermTraverser::queueReplacementWithParent(TIntermNode *parent,
+ TIntermNode *original,
+ TIntermNode *replacement,
+ OriginalNode originalStatus)
+{
+ bool originalBecomesChild = (originalStatus == OriginalNode::BECOMES_CHILD);
+ mReplacements.push_back(NodeUpdateEntry(parent, original, replacement, originalBecomesChild));
+}
+
+void TIntermTraverser::queueAccessChainReplacement(TIntermTyped *replacement)
+{
+ uint32_t ancestorIndex = 0;
+ TIntermTyped *toReplace = nullptr;
+ while (true)
+ {
+ TIntermNode *ancestor = getAncestorNode(ancestorIndex);
+ ASSERT(ancestor != nullptr);
+
+ TIntermBinary *asBinary = ancestor->getAsBinaryNode();
+ if (asBinary == nullptr ||
+ (asBinary->getOp() != EOpIndexDirect && asBinary->getOp() != EOpIndexIndirect))
+ {
+ break;
+ }
+
+ replacement = new TIntermBinary(asBinary->getOp(), replacement, asBinary->getRight());
+ toReplace = asBinary;
+
+ ++ancestorIndex;
+ }
+
+ if (toReplace == nullptr)
+ {
+ queueReplacement(replacement, OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ queueReplacementWithParent(getAncestorNode(ancestorIndex), toReplace, replacement,
+ OriginalNode::IS_DROPPED);
+ }
+}
+
+TLValueTrackingTraverser::TLValueTrackingTraverser(bool preVisitIn,
+ bool inVisitIn,
+ bool postVisitIn,
+ TSymbolTable *symbolTable)
+ : TIntermTraverser(preVisitIn, inVisitIn, postVisitIn, symbolTable),
+ mOperatorRequiresLValue(false),
+ mInFunctionCallOutParameter(false)
+{
+ ASSERT(symbolTable);
+}
+
+void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ bool visit = true;
+
+ TIntermSequence *sequence = node->getSequence();
+
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ if (visit)
+ {
+ size_t paramIndex = 0u;
+ for (auto *child : *sequence)
+ {
+ if (visit)
+ {
+ if (node->getFunction())
+ {
+ // Both built-ins and user defined functions should have the function symbol
+ // set.
+ ASSERT(paramIndex < node->getFunction()->getParamCount());
+ TQualifier qualifier =
+ node->getFunction()->getParam(paramIndex)->getType().getQualifier();
+ setInFunctionCallOutParameter(qualifier == EvqParamOut ||
+ qualifier == EvqParamInOut);
+ ++paramIndex;
+ }
+ else
+ {
+ ASSERT(node->isConstructor());
+ }
+ child->traverse(this);
+ if (inVisit)
+ {
+ if (child != sequence->back())
+ visit = node->visit(InVisit, this);
+ }
+ }
+ }
+ setInFunctionCallOutParameter(false);
+
+ if (visit && postVisit)
+ visit = node->visit(PostVisit, this);
+ }
+}
+
+void TIntermTraverser::traverseLoop(TIntermLoop *node)
+{
+ traverse(node);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.h b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.h
new file mode 100644
index 0000000000..3a48556a1f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.h
@@ -0,0 +1,379 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// IntermTraverse.h : base classes for AST traversers that walk the AST and
+// also have the ability to transform it by replacing nodes.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_INTERMTRAVERSE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_INTERMTRAVERSE_H_
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/Visit.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TSymbolTable;
+class TSymbolUniqueId;
+
+// For traversing the tree. User should derive from this class overriding the visit functions,
+// and then pass an object of the subclass to a traverse method of a node.
+//
+// The traverse*() functions may also be overridden to do other bookkeeping on the tree to provide
+// contextual information to the visit functions, such as whether the node is the target of an
+// assignment. This is complex to maintain and so should only be done in special cases.
+//
+// When using this, just fill in the methods for nodes you want visited.
+// Return false from a pre-visit to skip visiting that node's subtree.
+//
+// See also how to write AST transformations documentation:
+// https://github.com/google/angle/blob/master/doc/WritingShaderASTTransformations.md
+class TIntermTraverser : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TIntermTraverser(bool preVisitIn,
+ bool inVisitIn,
+ bool postVisitIn,
+ TSymbolTable *symbolTable = nullptr);
+ virtual ~TIntermTraverser();
+
+ virtual void visitSymbol(TIntermSymbol *node) {}
+ virtual void visitConstantUnion(TIntermConstantUnion *node) {}
+ virtual bool visitSwizzle(Visit visit, TIntermSwizzle *node) { return true; }
+ virtual bool visitBinary(Visit visit, TIntermBinary *node) { return true; }
+ virtual bool visitUnary(Visit visit, TIntermUnary *node) { return true; }
+ virtual bool visitTernary(Visit visit, TIntermTernary *node) { return true; }
+ virtual bool visitIfElse(Visit visit, TIntermIfElse *node) { return true; }
+ virtual bool visitSwitch(Visit visit, TIntermSwitch *node) { return true; }
+ virtual bool visitCase(Visit visit, TIntermCase *node) { return true; }
+ virtual void visitFunctionPrototype(TIntermFunctionPrototype *node) {}
+ virtual bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+ {
+ return true;
+ }
+ virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; }
+ virtual bool visitBlock(Visit visit, TIntermBlock *node) { return true; }
+ virtual bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+ {
+ return true;
+ }
+ virtual bool visitDeclaration(Visit visit, TIntermDeclaration *node) { return true; }
+ virtual bool visitLoop(Visit visit, TIntermLoop *node) { return true; }
+ virtual bool visitBranch(Visit visit, TIntermBranch *node) { return true; }
+ virtual void visitPreprocessorDirective(TIntermPreprocessorDirective *node) {}
+
+ // The traverse functions contain logic for iterating over the children of the node
+ // and calling the visit functions in the appropriate places. They also track some
+ // context that may be used by the visit functions.
+
+ // The generic traverse() function is used for nodes that don't need special handling.
+ // It's templated in order to avoid virtual function calls, this gains around 2% compiler
+ // performance.
+ template <typename T>
+ void traverse(T *node);
+
+ // Specialized traverse functions are implemented for node types where traversal logic may need
+ // to be overridden or where some special bookkeeping needs to be done.
+ virtual void traverseBinary(TIntermBinary *node);
+ virtual void traverseUnary(TIntermUnary *node);
+ virtual void traverseFunctionDefinition(TIntermFunctionDefinition *node);
+ virtual void traverseAggregate(TIntermAggregate *node);
+ virtual void traverseBlock(TIntermBlock *node);
+ virtual void traverseLoop(TIntermLoop *node);
+
+ int getMaxDepth() const { return mMaxDepth; }
+
+ // If traversers need to replace nodes, they can add the replacements in
+ // mReplacements/mMultiReplacements during traversal and the user of the traverser should call
+ // this function after traversal to perform them.
+ //
+ // Compiler is used to validate the tree. Node is the same given to traverse(). Returns false
+ // if the tree is invalid after update.
+ [[nodiscard]] bool updateTree(TCompiler *compiler, TIntermNode *node);
+
+ protected:
+ void setMaxAllowedDepth(int depth);
+
+ // Should only be called from traverse*() functions
+ bool incrementDepth(TIntermNode *current)
+ {
+ mMaxDepth = std::max(mMaxDepth, static_cast<int>(mPath.size()));
+ mPath.push_back(current);
+ return mMaxDepth < mMaxAllowedDepth;
+ }
+
+ // Should only be called from traverse*() functions
+ void decrementDepth() { mPath.pop_back(); }
+
+ int getCurrentTraversalDepth() const { return static_cast<int>(mPath.size()) - 1; }
+ int getCurrentBlockDepth() const { return static_cast<int>(mParentBlockStack.size()) - 1; }
+
+ // RAII helper for incrementDepth/decrementDepth
+ class [[nodiscard]] ScopedNodeInTraversalPath
+ {
+ public:
+ ScopedNodeInTraversalPath(TIntermTraverser *traverser, TIntermNode *current)
+ : mTraverser(traverser)
+ {
+ mWithinDepthLimit = mTraverser->incrementDepth(current);
+ }
+ ~ScopedNodeInTraversalPath() { mTraverser->decrementDepth(); }
+
+ bool isWithinDepthLimit() { return mWithinDepthLimit; }
+
+ private:
+ TIntermTraverser *mTraverser;
+ bool mWithinDepthLimit;
+ };
+ // Optimized traversal functions for leaf nodes directly access ScopedNodeInTraversalPath.
+ friend void TIntermSymbol::traverse(TIntermTraverser *);
+ friend void TIntermConstantUnion::traverse(TIntermTraverser *);
+ friend void TIntermFunctionPrototype::traverse(TIntermTraverser *);
+
+ TIntermNode *getParentNode() const
+ {
+ return mPath.size() <= 1 ? nullptr : mPath[mPath.size() - 2u];
+ }
+
+ // Return the nth ancestor of the node being traversed. getAncestorNode(0) == getParentNode()
+ TIntermNode *getAncestorNode(unsigned int n) const
+ {
+ if (mPath.size() > n + 1u)
+ {
+ return mPath[mPath.size() - n - 2u];
+ }
+ return nullptr;
+ }
+
+ // Returns what child index is currently being visited. For example when visiting the children
+ // of an aggregate, it can be used to find out which argument of the parent (aggregate) node
+ // they correspond to. Only valid in the PreVisit call of the child.
+ size_t getParentChildIndex(Visit visit) const
+ {
+ ASSERT(visit == PreVisit);
+ return mCurrentChildIndex;
+ }
+ // Returns what child index has just been processed. Only valid in the InVisit and PostVisit
+ // calls of the parent node.
+ size_t getLastTraversedChildIndex(Visit visit) const
+ {
+ ASSERT(visit != PreVisit);
+ return mCurrentChildIndex;
+ }
+
+ const TIntermBlock *getParentBlock() const;
+
+ TIntermNode *getRootNode() const
+ {
+ ASSERT(!mPath.empty());
+ return mPath.front();
+ }
+
+ void pushParentBlock(TIntermBlock *node);
+ void incrementParentBlockPos();
+ void popParentBlock();
+
+ // To replace a single node with multiple nodes in the parent aggregate. May be used with blocks
+ // but also with other nodes like declarations.
+ struct NodeReplaceWithMultipleEntry
+ {
+ NodeReplaceWithMultipleEntry(TIntermAggregateBase *parentIn,
+ TIntermNode *originalIn,
+ TIntermSequence &&replacementsIn)
+ : parent(parentIn), original(originalIn), replacements(std::move(replacementsIn))
+ {}
+
+ TIntermAggregateBase *parent;
+ TIntermNode *original;
+ TIntermSequence replacements;
+ };
+
+ // Helper to insert statements in the parent block of the node currently being traversed.
+ // The statements will be inserted before the node being traversed once updateTree is called.
+ // Should only be called during PreVisit or PostVisit if called from block nodes.
+ // Note that two insertions to the same position in the same block are not supported.
+ void insertStatementsInParentBlock(const TIntermSequence &insertions);
+
+ // Same as above, but supports simultaneous insertion of statements before and after the node
+ // currently being traversed.
+ void insertStatementsInParentBlock(const TIntermSequence &insertionsBefore,
+ const TIntermSequence &insertionsAfter);
+
+ // Helper to insert a single statement.
+ void insertStatementInParentBlock(TIntermNode *statement);
+
+ // Explicitly specify where to insert statements. The statements are inserted before and after
+ // the specified position. The statements will be inserted once updateTree is called. Note that
+ // two insertions to the same position in the same block are not supported.
+ void insertStatementsInBlockAtPosition(TIntermBlock *parent,
+ size_t position,
+ const TIntermSequence &insertionsBefore,
+ const TIntermSequence &insertionsAfter);
+
+ enum class OriginalNode
+ {
+ BECOMES_CHILD,
+ IS_DROPPED
+ };
+
+ void clearReplacementQueue();
+
+ // Replace the node currently being visited with replacement.
+ void queueReplacement(TIntermNode *replacement, OriginalNode originalStatus);
+ // Explicitly specify a node to replace with replacement.
+ void queueReplacementWithParent(TIntermNode *parent,
+ TIntermNode *original,
+ TIntermNode *replacement,
+ OriginalNode originalStatus);
+ // Walk the ancestors and replace the access chain that leads to this symbol. This fixes up the
+ // types of the intermediate nodes, so it should be used when the type of the symbol changes.
+ // The AST transformation must still visit the (indirect) index nodes to transform the
+ // expression inside those nodes. Note that due to the way these replacements work, the AST
+ // transformation should not attempt to replace the actual index node itself, but only a subnode
+ // of that.
+ //
+ // Node 1 Node 6
+ // EOpIndexDirect EOpIndexDirect
+ // / \ / \
+ // Node 2 Node 3 Node 7 Node 3
+ // EOpIndexIndirect N --> replaced with --> EOpIndexIndirect N
+ // / \ / \
+ // Node 4 Node 5 Node 8 Node 5
+ // symbol expression replacement expression
+ // ^ ^
+ // | |
+ // This symbol is being replaced, This node is directly placed in the
+ // and the replacement is given new access chain, and its parent is
+ // to this function. is changed. This is why a
+ // replacment attempt for this node
+ // itself will not work.
+ //
+ void queueAccessChainReplacement(TIntermTyped *replacement);
+
+ const bool preVisit;
+ const bool inVisit;
+ const bool postVisit;
+
+ int mMaxDepth;
+ int mMaxAllowedDepth;
+
+ bool mInGlobalScope;
+
+ // During traversing, save all the changes that need to happen into
+ // mReplacements/mMultiReplacements, then do them by calling updateTree().
+ // Multi replacements are processed after single replacements.
+ std::vector<NodeReplaceWithMultipleEntry> mMultiReplacements;
+
+ TSymbolTable *mSymbolTable;
+
+ private:
+ // To insert multiple nodes into the parent block.
+ struct NodeInsertMultipleEntry
+ {
+ NodeInsertMultipleEntry(TIntermBlock *_parent,
+ TIntermSequence::size_type _position,
+ TIntermSequence _insertionsBefore,
+ TIntermSequence _insertionsAfter)
+ : parent(_parent),
+ position(_position),
+ insertionsBefore(_insertionsBefore),
+ insertionsAfter(_insertionsAfter)
+ {}
+
+ TIntermBlock *parent;
+ TIntermSequence::size_type position;
+ TIntermSequence insertionsBefore;
+ TIntermSequence insertionsAfter;
+ };
+
+ static bool CompareInsertion(const NodeInsertMultipleEntry &a,
+ const NodeInsertMultipleEntry &b);
+
+ // To replace a single node with another on the parent node
+ struct NodeUpdateEntry
+ {
+ NodeUpdateEntry(TIntermNode *_parent,
+ TIntermNode *_original,
+ TIntermNode *_replacement,
+ bool _originalBecomesChildOfReplacement)
+ : parent(_parent),
+ original(_original),
+ replacement(_replacement),
+ originalBecomesChildOfReplacement(_originalBecomesChildOfReplacement)
+ {}
+
+ TIntermNode *parent;
+ TIntermNode *original;
+ TIntermNode *replacement;
+ bool originalBecomesChildOfReplacement;
+ };
+
+ struct ParentBlock
+ {
+ ParentBlock(TIntermBlock *nodeIn, TIntermSequence::size_type posIn)
+ : node(nodeIn), pos(posIn)
+ {}
+
+ TIntermBlock *node;
+ TIntermSequence::size_type pos;
+ };
+
+ std::vector<NodeInsertMultipleEntry> mInsertions;
+ std::vector<NodeUpdateEntry> mReplacements;
+
+ // All the nodes from root to the current node during traversing.
+ TVector<TIntermNode *> mPath;
+ // The current child of parent being traversed.
+ size_t mCurrentChildIndex;
+
+ // All the code blocks from the root to the current node's parent during traversal.
+ std::vector<ParentBlock> mParentBlockStack;
+};
+
+// Traverser parent class that tracks where a node is a destination of a write operation and so is
+// required to be an l-value.
+class TLValueTrackingTraverser : public TIntermTraverser
+{
+ public:
+ TLValueTrackingTraverser(bool preVisit,
+ bool inVisit,
+ bool postVisit,
+ TSymbolTable *symbolTable);
+ ~TLValueTrackingTraverser() override {}
+
+ void traverseBinary(TIntermBinary *node) final;
+ void traverseUnary(TIntermUnary *node) final;
+ void traverseAggregate(TIntermAggregate *node) final;
+
+ protected:
+ bool isLValueRequiredHere() const
+ {
+ return mOperatorRequiresLValue || mInFunctionCallOutParameter;
+ }
+
+ private:
+ // Track whether an l-value is required in the node that is currently being traversed by the
+ // surrounding operator.
+ // Use isLValueRequiredHere to check all conditions which require an l-value.
+ void setOperatorRequiresLValue(bool lValueRequired)
+ {
+ mOperatorRequiresLValue = lValueRequired;
+ }
+ bool operatorRequiresLValue() const { return mOperatorRequiresLValue; }
+
+ // Track whether an l-value is required inside a function call.
+ void setInFunctionCallOutParameter(bool inOutParameter);
+ bool isInFunctionCallOutParameter() const;
+
+ bool mOperatorRequiresLValue;
+ bool mInFunctionCallOutParameter;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_INTERMTRAVERSE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/NodeSearch.h b/gfx/angle/checkout/src/compiler/translator/tree_util/NodeSearch.h
new file mode 100644
index 0000000000..7764a2ebe3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/NodeSearch.h
@@ -0,0 +1,56 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// NodeSearch.h: Utilities for searching translator node graphs
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_NODESEARCH_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_NODESEARCH_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+template <class Parent>
+class NodeSearchTraverser : public TIntermTraverser
+{
+ public:
+ NodeSearchTraverser() : TIntermTraverser(true, false, false), mFound(false) {}
+
+ bool found() const { return mFound; }
+
+ static bool search(TIntermNode *node)
+ {
+ Parent searchTraverser;
+ node->traverse(&searchTraverser);
+ return searchTraverser.found();
+ }
+
+ protected:
+ bool mFound;
+};
+
+class FindDiscard : public NodeSearchTraverser<FindDiscard>
+{
+ public:
+ bool visitBranch(Visit visit, TIntermBranch *node) override
+ {
+ switch (node->getFlowOp())
+ {
+ case EOpKill:
+ mFound = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return !mFound;
+ }
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_NODESEARCH_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/NodeType.h b/gfx/angle/checkout/src/compiler/translator/tree_util/NodeType.h
new file mode 100644
index 0000000000..4ab63dbebb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/NodeType.h
@@ -0,0 +1,155 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_NODETYPE_H_
+#define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_NODETYPE_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+enum class NodeType
+{
+ Unknown,
+ Symbol,
+ ConstantUnion,
+ FunctionPrototype,
+ PreprocessorDirective,
+ Unary,
+ Binary,
+ Ternary,
+ Swizzle,
+ IfElse,
+ Switch,
+ Case,
+ FunctionDefinition,
+ Aggregate,
+ Block,
+ GlobalQualifierDeclaration,
+ Declaration,
+ Loop,
+ Branch,
+};
+
+// This is a function like object instead of a function that stack allocates this because
+// TIntermTraverser is a heavy object to construct.
+class GetNodeType : private TIntermTraverser
+{
+ NodeType nodeType;
+
+ public:
+ GetNodeType() : TIntermTraverser(true, false, false) {}
+
+ NodeType operator()(TIntermNode &node)
+ {
+ node.visit(Visit::PreVisit, this);
+ return nodeType;
+ }
+
+ private:
+ void visitSymbol(TIntermSymbol *) override { nodeType = NodeType::Symbol; }
+
+ void visitConstantUnion(TIntermConstantUnion *) override { nodeType = NodeType::ConstantUnion; }
+
+ void visitFunctionPrototype(TIntermFunctionPrototype *) override
+ {
+ nodeType = NodeType::FunctionPrototype;
+ }
+
+ void visitPreprocessorDirective(TIntermPreprocessorDirective *) override
+ {
+ nodeType = NodeType::PreprocessorDirective;
+ }
+
+ bool visitSwizzle(Visit, TIntermSwizzle *) override
+ {
+ nodeType = NodeType::Swizzle;
+ return false;
+ }
+
+ bool visitBinary(Visit, TIntermBinary *) override
+ {
+ nodeType = NodeType::Binary;
+ return false;
+ }
+
+ bool visitUnary(Visit, TIntermUnary *) override
+ {
+ nodeType = NodeType::Unary;
+ return false;
+ }
+
+ bool visitTernary(Visit, TIntermTernary *) override
+ {
+ nodeType = NodeType::Ternary;
+ return false;
+ }
+
+ bool visitIfElse(Visit, TIntermIfElse *) override
+ {
+ nodeType = NodeType::IfElse;
+ return false;
+ }
+
+ bool visitSwitch(Visit, TIntermSwitch *) override
+ {
+ nodeType = NodeType::Switch;
+ return false;
+ }
+
+ bool visitCase(Visit, TIntermCase *) override
+ {
+ nodeType = NodeType::Case;
+ return false;
+ }
+
+ bool visitFunctionDefinition(Visit, TIntermFunctionDefinition *) override
+ {
+ nodeType = NodeType::FunctionDefinition;
+ return false;
+ }
+
+ bool visitAggregate(Visit, TIntermAggregate *) override
+ {
+ nodeType = NodeType::Aggregate;
+ return false;
+ }
+
+ bool visitBlock(Visit, TIntermBlock *) override
+ {
+ nodeType = NodeType::Block;
+ return false;
+ }
+
+ bool visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *) override
+ {
+ nodeType = NodeType::GlobalQualifierDeclaration;
+ return false;
+ }
+
+ bool visitDeclaration(Visit, TIntermDeclaration *) override
+ {
+ nodeType = NodeType::Declaration;
+ return false;
+ }
+
+ bool visitLoop(Visit, TIntermLoop *) override
+ {
+ nodeType = NodeType::Loop;
+ return false;
+ }
+
+ bool visitBranch(Visit, TIntermBranch *) override
+ {
+ nodeType = NodeType::Branch;
+ return false;
+ }
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_NODETYPE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp
new file mode 100644
index 0000000000..ddbb22685d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp
@@ -0,0 +1,175 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+//
+// ReplaceArrayOfMatrixVarying: Find any references to array of matrices varying
+// and replace it with array of vectors.
+//
+
+#include "compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.h"
+
+#include <vector>
+
+#include "common/bitset_utils.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+// We create two variables to replace the given varying:
+// - The new varying which is an array of vectors to be used at input/ouput only.
+// - The new global variable which is a same type as given variable, to temporarily be used
+// as replacements for assignments, arithmetic ops and so on. During input/ouput phrase, this temp
+// variable will be copied from/to the array of vectors variable above.
+// NOTE(hqle): Consider eliminating the need for using temp variable.
+
+namespace
+{
+class CollectVaryingTraverser : public TIntermTraverser
+{
+ public:
+ CollectVaryingTraverser(std::vector<const TVariable *> *varyingsOut)
+ : TIntermTraverser(true, false, false), mVaryingsOut(varyingsOut)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ if (sequence.size() != 1)
+ {
+ return false;
+ }
+
+ TIntermTyped *variableType = sequence.front()->getAsTyped();
+ if (!variableType || !IsVarying(variableType->getQualifier()) ||
+ !variableType->isMatrix() || !variableType->isArray())
+ {
+ return false;
+ }
+
+ TIntermSymbol *variableSymbol = variableType->getAsSymbolNode();
+ if (!variableSymbol)
+ {
+ return false;
+ }
+
+ mVaryingsOut->push_back(&variableSymbol->variable());
+
+ return false;
+ }
+
+ private:
+ std::vector<const TVariable *> *mVaryingsOut;
+};
+} // namespace
+
+[[nodiscard]] bool ReplaceArrayOfMatrixVarying(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TVariable *varying)
+{
+ const TType &type = varying->getType();
+
+ // Create global variable to temporarily acts as the given variable in places such as
+ // arithmetic, assignments an so on.
+ TType *tmpReplacementType = new TType(type);
+ tmpReplacementType->setQualifier(EvqGlobal);
+
+ TVariable *tempReplaceVar = new TVariable(
+ symbolTable, ImmutableString(std::string("ANGLE_AOM_Temp_") + varying->name().data()),
+ tmpReplacementType, SymbolType::AngleInternal);
+
+ if (!ReplaceVariable(compiler, root, varying, tempReplaceVar))
+ {
+ return false;
+ }
+
+ // Create array of vectors type
+ TType *varyingReplaceType = new TType(type);
+ varyingReplaceType->toMatrixColumnType();
+ varyingReplaceType->toArrayElementType();
+ varyingReplaceType->makeArray(type.getCols() * type.getOutermostArraySize());
+
+ TVariable *varyingReplaceVar =
+ new TVariable(symbolTable, varying->name(), varyingReplaceType, SymbolType::UserDefined);
+
+ TIntermSymbol *varyingReplaceDeclarator = new TIntermSymbol(varyingReplaceVar);
+ TIntermDeclaration *varyingReplaceDecl = new TIntermDeclaration;
+ varyingReplaceDecl->appendDeclarator(varyingReplaceDeclarator);
+ root->insertStatement(0, varyingReplaceDecl);
+
+ // Copy from/to the temp variable
+ TIntermBlock *reassignBlock = new TIntermBlock;
+ TIntermSymbol *tempReplaceSymbol = new TIntermSymbol(tempReplaceVar);
+ TIntermSymbol *varyingReplaceSymbol = new TIntermSymbol(varyingReplaceVar);
+ bool isInput = IsVaryingIn(type.getQualifier());
+
+ for (unsigned int i = 0; i < type.getOutermostArraySize(); ++i)
+ {
+ TIntermBinary *tempMatrixIndexed =
+ new TIntermBinary(EOpIndexDirect, tempReplaceSymbol->deepCopy(), CreateIndexNode(i));
+ for (uint8_t col = 0; col < type.getCols(); ++col)
+ {
+
+ TIntermBinary *tempMatrixColIndexed = new TIntermBinary(
+ EOpIndexDirect, tempMatrixIndexed->deepCopy(), CreateIndexNode(col));
+ TIntermBinary *vectorIndexed =
+ new TIntermBinary(EOpIndexDirect, varyingReplaceSymbol->deepCopy(),
+ CreateIndexNode(i * type.getCols() + col));
+ TIntermBinary *assignment;
+ if (isInput)
+ {
+ assignment = new TIntermBinary(EOpAssign, tempMatrixColIndexed, vectorIndexed);
+ }
+ else
+ {
+ assignment = new TIntermBinary(EOpAssign, vectorIndexed, tempMatrixColIndexed);
+ }
+ reassignBlock->appendStatement(assignment);
+ }
+ }
+
+ if (isInput)
+ {
+ TIntermFunctionDefinition *main = FindMain(root);
+ main->getBody()->insertStatement(0, reassignBlock);
+ return compiler->validateAST(root);
+ }
+ else
+ {
+ return RunAtTheEndOfShader(compiler, root, reassignBlock, symbolTable);
+ }
+}
+
+[[nodiscard]] bool ReplaceArrayOfMatrixVaryings(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ std::vector<const TVariable *> arrayOfMatrixVars;
+ CollectVaryingTraverser varCollector(&arrayOfMatrixVars);
+ root->traverse(&varCollector);
+
+ for (const TVariable *var : arrayOfMatrixVars)
+ {
+ if (!ReplaceArrayOfMatrixVarying(compiler, root, symbolTable, var))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.h b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.h
new file mode 100644
index 0000000000..62b6b320af
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+//
+// ReplaceArrayOfMatrixVarying: Find any references to array of matrices varying
+// and replace it with array of vectors.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_REPLACEARRAYOFMATRIXVARYING_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_REPLACEARRAYOFMATRIXVARYING_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+class TVariable;
+
+[[nodiscard]] bool ReplaceArrayOfMatrixVarying(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TVariable *varying);
+
+[[nodiscard]] bool ReplaceArrayOfMatrixVaryings(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.cpp
new file mode 100644
index 0000000000..a8379f48f1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.cpp
@@ -0,0 +1,591 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ReplaceClipCullDistanceVariable.cpp: Find any references to gl_ClipDistance or gl_CullDistance
+// and replace it with ANGLEClipDistance or ANGLECullDistance.
+//
+
+#include "compiler/translator/tree_util/ReplaceClipCullDistanceVariable.h"
+
+#include "common/bitset_utils.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+#include "compiler/translator/tree_util/RunAtTheBeginningOfShader.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+namespace sh
+{
+namespace
+{
+
+using ClipCullDistanceIdxSet = angle::BitSet<32>;
+
+typedef TIntermNode *AssignFunc(const unsigned int index,
+ TIntermSymbol *left,
+ TIntermSymbol *right,
+ const TIntermTyped *enableFlags);
+
+template <typename Variable>
+const Variable *FindVariable(const std::vector<Variable> &mVars, const ImmutableString &name)
+{
+ for (const Variable &var : mVars)
+ {
+ if (name == var.instanceName)
+ {
+ return &var;
+ }
+ }
+
+ return nullptr;
+}
+
+// Traverse the tree and collect the redeclaration and all constant index references of
+// gl_ClipDistance/gl_CullDistance
+class GLClipCullDistanceReferenceTraverser : public TIntermTraverser
+{
+ public:
+ GLClipCullDistanceReferenceTraverser(const TIntermSymbol **redeclaredSymOut,
+ bool *nonConstIdxUsedOut,
+ unsigned int *maxConstIdxOut,
+ ClipCullDistanceIdxSet *constIndicesOut,
+ TQualifier targetQualifier)
+ : TIntermTraverser(true, false, false),
+ mRedeclaredSym(redeclaredSymOut),
+ mUseNonConstClipCullDistanceIndex(nonConstIdxUsedOut),
+ mMaxConstClipCullDistanceIndex(maxConstIdxOut),
+ mConstClipCullDistanceIndices(constIndicesOut),
+ mTargetQualifier(targetQualifier)
+ {
+ *mRedeclaredSym = nullptr;
+ *mUseNonConstClipCullDistanceIndex = false;
+ *mMaxConstClipCullDistanceIndex = 0;
+ mConstClipCullDistanceIndices->reset();
+ }
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ // If gl_ClipDistance/gl_CullDistance is redeclared, we need to collect its information
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ if (sequence.size() != 1)
+ {
+ return true;
+ }
+
+ TIntermSymbol *variable = sequence.front()->getAsSymbolNode();
+ if (variable == nullptr || variable->getType().getQualifier() != mTargetQualifier)
+ {
+ return true;
+ }
+
+ *mRedeclaredSym = variable->getAsSymbolNode();
+
+ return true;
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TOperator op = node->getOp();
+ if (op != EOpIndexDirect && op != EOpIndexIndirect)
+ {
+ return true;
+ }
+
+ // gl_ClipDistance / gl_CullDistance
+ TIntermTyped *left = node->getLeft()->getAsTyped();
+ if (!left)
+ {
+ return true;
+ }
+
+ ASSERT(op == EOpIndexDirect || op == EOpIndexIndirect);
+
+ TIntermSymbol *clipCullDistance = left->getAsSymbolNode();
+ if (!clipCullDistance)
+ {
+ return true;
+ }
+ if (clipCullDistance->getType().getQualifier() != mTargetQualifier)
+ {
+ return true;
+ }
+
+ const TConstantUnion *constIdx = node->getRight()->getConstantValue();
+ if (!constIdx)
+ {
+ *mUseNonConstClipCullDistanceIndex = true;
+ }
+ else
+ {
+ unsigned int idx = 0;
+ switch (constIdx->getType())
+ {
+ case EbtInt:
+ idx = constIdx->getIConst();
+ break;
+ case EbtUInt:
+ idx = constIdx->getUConst();
+ break;
+ case EbtFloat:
+ idx = static_cast<unsigned int>(constIdx->getFConst());
+ break;
+ case EbtBool:
+ idx = constIdx->getBConst() ? 1 : 0;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ ASSERT(idx < mConstClipCullDistanceIndices->size());
+ mConstClipCullDistanceIndices->set(idx);
+
+ *mMaxConstClipCullDistanceIndex = std::max(*mMaxConstClipCullDistanceIndex, idx);
+ }
+
+ return true;
+ }
+
+ private:
+ const TIntermSymbol **mRedeclaredSym;
+ // Flag indicating whether there is at least one reference of gl_ClipDistance with non-constant
+ // index
+ bool *mUseNonConstClipCullDistanceIndex;
+ // Max constant index that is used to reference gl_ClipDistance
+ unsigned int *mMaxConstClipCullDistanceIndex;
+ // List of constant index reference of gl_ClipDistance
+ ClipCullDistanceIdxSet *mConstClipCullDistanceIndices;
+ // Qualifier for gl_ClipDistance/gl_CullDistance
+ const TQualifier mTargetQualifier;
+};
+
+// Replace all symbolic occurrences of given variables except one symbol.
+class ReplaceVariableExceptOneTraverser : public TIntermTraverser
+{
+ public:
+ ReplaceVariableExceptOneTraverser(const TVariable *toBeReplaced,
+ const TIntermTyped *replacement,
+ const TIntermSymbol *exception)
+ : TIntermTraverser(true, false, false),
+ mToBeReplaced(toBeReplaced),
+ mException(exception),
+ mReplacement(replacement)
+ {}
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == mToBeReplaced && node != mException)
+ {
+ queueReplacement(mReplacement->deepCopy(), OriginalNode::IS_DROPPED);
+ }
+ }
+
+ private:
+ const TVariable *const mToBeReplaced;
+ const TIntermSymbol *const mException;
+ const TIntermTyped *const mReplacement;
+};
+
+TIntermNode *simpleAssignFunc(const unsigned int index,
+ TIntermSymbol *leftSymbol,
+ TIntermSymbol *rightSymbol,
+ const TIntermTyped * /*enableFlags*/)
+{
+ // leftSymbol[index] = rightSymbol[index]
+ // E.g., ANGLEClipDistance[index] = gl_ClipDistance[index]
+ TIntermBinary *left =
+ new TIntermBinary(EOpIndexDirect, leftSymbol->deepCopy(), CreateIndexNode(index));
+ TIntermBinary *right =
+ new TIntermBinary(EOpIndexDirect, rightSymbol->deepCopy(), CreateIndexNode(index));
+
+ return new TIntermBinary(EOpAssign, left, right);
+}
+
+// This is only used for gl_ClipDistance
+TIntermNode *assignFuncWithEnableFlags(const unsigned int index,
+ TIntermSymbol *leftSymbol,
+ TIntermSymbol *rightSymbol,
+ const TIntermTyped *enableFlags)
+{
+ // if (ANGLEUniforms.clipDistancesEnabled & (0x1 << index))
+ // gl_ClipDistance[index] = ANGLEClipDistance[index];
+ // else
+ // gl_ClipDistance[index] = 0;
+ TIntermConstantUnion *bitMask = CreateUIntNode(0x1 << index);
+ TIntermBinary *bitwiseAnd = new TIntermBinary(EOpBitwiseAnd, enableFlags->deepCopy(), bitMask);
+ TIntermBinary *nonZero = new TIntermBinary(EOpNotEqual, bitwiseAnd, CreateUIntNode(0));
+
+ TIntermBinary *left =
+ new TIntermBinary(EOpIndexDirect, leftSymbol->deepCopy(), CreateIndexNode(index));
+ TIntermBinary *right =
+ new TIntermBinary(EOpIndexDirect, rightSymbol->deepCopy(), CreateIndexNode(index));
+ TIntermBinary *assignment = new TIntermBinary(EOpAssign, left, right);
+ TIntermBlock *trueBlock = new TIntermBlock();
+ trueBlock->appendStatement(assignment);
+
+ TIntermBinary *zeroAssignment =
+ new TIntermBinary(EOpAssign, left->deepCopy(), CreateFloatNode(0, EbpMedium));
+ TIntermBlock *falseBlock = new TIntermBlock();
+ falseBlock->appendStatement(zeroAssignment);
+
+ return new TIntermIfElse(nonZero, trueBlock, falseBlock);
+}
+
+class ReplaceClipCullDistanceAssignments : angle::NonCopyable
+{
+ public:
+ ReplaceClipCullDistanceAssignments(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TVariable *glClipCullDistanceVar,
+ const TIntermSymbol *redeclaredGlClipDistance,
+ const ImmutableString &angleVarName)
+ : mCompiler(compiler),
+ mRoot(root),
+ mSymbolTable(symbolTable),
+ mGlVar(glClipCullDistanceVar),
+ mRedeclaredGLVar(redeclaredGlClipDistance),
+ mANGLEVarName(angleVarName)
+ {
+ mEnabledDistances = 0;
+ }
+
+ unsigned int getEnabledClipCullDistance(const bool useNonConstIndex,
+ const unsigned int maxConstIndex);
+ const TVariable *declareANGLEVariable(const TVariable *originalVariable);
+ bool assignOriginalValueToANGLEVariable(const GLenum shaderType);
+ bool assignANGLEValueToOriginalVariable(const GLenum shaderType,
+ const bool isRedeclared,
+ const TIntermTyped *enableFlags,
+ const ClipCullDistanceIdxSet *constIndices);
+
+ private:
+ bool assignOriginalValueToANGLEVariableImpl();
+ bool assignANGLEValueToOriginalVariableImpl(const bool isRedeclared,
+ const TIntermTyped *enableFlags,
+ const ClipCullDistanceIdxSet *constIndices,
+ AssignFunc assignFunc);
+
+ // Common variables for replacing gl_Clip/CullDistances with ANGLEClip/CullDistances
+ TCompiler *mCompiler;
+ TIntermBlock *mRoot;
+ TSymbolTable *mSymbolTable;
+
+ const TVariable *mGlVar;
+ const TIntermSymbol *mRedeclaredGLVar;
+ const ImmutableString mANGLEVarName;
+
+ unsigned int mEnabledDistances;
+ const TVariable *mANGLEVar;
+};
+
+unsigned int ReplaceClipCullDistanceAssignments::getEnabledClipCullDistance(
+ const bool useNonConstIndex,
+ const unsigned int maxConstIndex)
+{
+ if (mRedeclaredGLVar)
+ {
+ // If array is redeclared by user, use that redeclared size.
+ mEnabledDistances = mRedeclaredGLVar->getType().getOutermostArraySize();
+ }
+ else if (!useNonConstIndex)
+ {
+ ASSERT(maxConstIndex < mGlVar->getType().getOutermostArraySize());
+ // Only use constant index, then use max array index used.
+ mEnabledDistances = maxConstIndex + 1;
+ }
+
+ return mEnabledDistances;
+}
+
+const TVariable *ReplaceClipCullDistanceAssignments::declareANGLEVariable(
+ const TVariable *originalVariable)
+{
+ ASSERT(mEnabledDistances > 0);
+
+ TType *clipCullDistanceType = new TType(originalVariable->getType());
+ clipCullDistanceType->setQualifier(EvqGlobal);
+ clipCullDistanceType->toArrayBaseType();
+ clipCullDistanceType->makeArray(mEnabledDistances);
+
+ mANGLEVar =
+ new TVariable(mSymbolTable, mANGLEVarName, clipCullDistanceType, SymbolType::AngleInternal);
+
+ TIntermSymbol *clipCullDistanceDeclarator = new TIntermSymbol(mANGLEVar);
+ TIntermDeclaration *clipCullDistanceDecl = new TIntermDeclaration;
+ clipCullDistanceDecl->appendDeclarator(clipCullDistanceDeclarator);
+
+ // Must declare ANGLEClipdistance/ANGLECullDistance before any function, since
+ // gl_ClipDistance/gl_CullDistance might be accessed within a function declared before main.
+ mRoot->insertStatement(0, clipCullDistanceDecl);
+
+ return mANGLEVar;
+}
+
+bool ReplaceClipCullDistanceAssignments::assignOriginalValueToANGLEVariableImpl()
+{
+ ASSERT(mEnabledDistances > 0);
+
+ TIntermBlock *readBlock = new TIntermBlock;
+ TIntermSymbol *glClipCullDistanceSymbol = new TIntermSymbol(mGlVar);
+ TIntermSymbol *clipCullDistanceSymbol = new TIntermSymbol(mANGLEVar);
+
+ for (unsigned int i = 0; i < mEnabledDistances; i++)
+ {
+ readBlock->appendStatement(
+ simpleAssignFunc(i, clipCullDistanceSymbol, glClipCullDistanceSymbol, nullptr));
+ }
+
+ return RunAtTheBeginningOfShader(mCompiler, mRoot, readBlock);
+}
+
+bool ReplaceClipCullDistanceAssignments::assignANGLEValueToOriginalVariableImpl(
+ const bool isRedeclared,
+ const TIntermTyped *enableFlags,
+ const ClipCullDistanceIdxSet *constIndices,
+ AssignFunc assignFunc)
+{
+ ASSERT(mEnabledDistances > 0);
+
+ TIntermBlock *assignBlock = new TIntermBlock;
+ TIntermSymbol *glClipCullDistanceSymbol = new TIntermSymbol(mGlVar);
+ TIntermSymbol *clipCullDistanceSymbol = new TIntermSymbol(mANGLEVar);
+
+ // The array size is decided by either redeclaring the variable or accessing the variable with a
+ // integral constant index. And this size is the count of the enabled value. So, if the index
+ // which is greater than the array size, is used to access the variable, this access will be
+ // ignored.
+ if (isRedeclared || !constIndices)
+ {
+ for (unsigned int i = 0; i < mEnabledDistances; ++i)
+ {
+ assignBlock->appendStatement(
+ assignFunc(i, glClipCullDistanceSymbol, clipCullDistanceSymbol, enableFlags));
+ }
+ }
+ else
+ {
+ // Assign ANGLEClip/CullDistance[i]'s value to gl_Clip/CullDistance[i] if i is in the
+ // constant indices list. Those elements whose index is not in the constant index list will
+ // be zeroise for initialization.
+ for (unsigned int i = 0; i < mEnabledDistances; ++i)
+ {
+ if (constIndices->test(i))
+ {
+ assignBlock->appendStatement(
+ assignFunc(i, glClipCullDistanceSymbol, clipCullDistanceSymbol, enableFlags));
+ }
+ else
+ {
+ // gl_Clip/CullDistance[i] = 0;
+ TIntermBinary *left = new TIntermBinary(
+ EOpIndexDirect, glClipCullDistanceSymbol->deepCopy(), CreateIndexNode(i));
+ TIntermBinary *zeroAssignment =
+ new TIntermBinary(EOpAssign, left, CreateFloatNode(0, EbpMedium));
+ assignBlock->appendStatement(zeroAssignment);
+ }
+ }
+ }
+
+ return RunAtTheEndOfShader(mCompiler, mRoot, assignBlock, mSymbolTable);
+}
+
+[[nodiscard]] bool ReplaceClipCullDistanceAssignments::assignOriginalValueToANGLEVariable(
+ const GLenum shaderType)
+{
+ switch (shaderType)
+ {
+ case GL_VERTEX_SHADER:
+ // Vertex shader can use gl_Clip/CullDistance as a output only
+ break;
+ case GL_FRAGMENT_SHADER:
+ {
+ // These shader types can use gl_Clip/CullDistance as input
+ if (!assignOriginalValueToANGLEVariableImpl())
+ {
+ return false;
+ }
+ break;
+ }
+ default:
+ {
+ UNREACHABLE();
+ return false;
+ }
+ }
+
+ return true;
+}
+
+[[nodiscard]] bool ReplaceClipCullDistanceAssignments::assignANGLEValueToOriginalVariable(
+ const GLenum shaderType,
+ const bool isRedeclared,
+ const TIntermTyped *enableFlags,
+ const ClipCullDistanceIdxSet *constIndices)
+{
+ switch (shaderType)
+ {
+ case GL_VERTEX_SHADER:
+ {
+ // Vertex shader can use gl_Clip/CullDistance as output.
+ // If the enabled gl_Clip/CullDistances are not initialized, results are undefined.
+ // EXT_clip_cull_distance spec :
+ // The shader must also set all values in gl_ClipDistance that have been enabled via the
+ // OpenGL ES API, or results are undefined. Values written into gl_ClipDistance for
+ // planes that are not enabled have no effect.
+ // ...
+ // Shaders writing gl_CullDistance must write all enabled distances, or culling results
+ // are undefined.
+ if (!assignANGLEValueToOriginalVariableImpl(
+ isRedeclared, enableFlags, constIndices,
+ enableFlags ? assignFuncWithEnableFlags : simpleAssignFunc))
+ {
+ return false;
+ }
+ break;
+ }
+ case GL_FRAGMENT_SHADER:
+ // Fragment shader can use gl_Clip/CullDistance as input only
+ break;
+ default:
+ {
+ UNREACHABLE();
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// Common code to transform gl_ClipDistance and gl_CullDistance. Comments reference
+// gl_ClipDistance, but are also applicable to gl_CullDistance.
+[[nodiscard]] bool ReplaceClipCullDistanceAssignmentsImpl(
+ TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const GLenum shaderType,
+ const TIntermTyped *clipDistanceEnableFlags,
+ const char *builtInName,
+ const char *replacementName,
+ TQualifier builtInQualifier)
+{
+ // Collect all constant index references of gl_ClipDistance
+ ImmutableString name(builtInName);
+ ClipCullDistanceIdxSet constIndices;
+ bool useNonConstIndex = false;
+ const TIntermSymbol *redeclaredBuiltIn = nullptr;
+ unsigned int maxConstIndex = 0;
+ GLClipCullDistanceReferenceTraverser indexTraverser(
+ &redeclaredBuiltIn, &useNonConstIndex, &maxConstIndex, &constIndices, builtInQualifier);
+ root->traverse(&indexTraverser);
+ if (!useNonConstIndex && constIndices.none())
+ {
+ // No references of gl_ClipDistance
+ return true;
+ }
+
+ // Retrieve gl_ClipDistance variable reference
+ // Search user redeclared gl_ClipDistance first
+ const TVariable *builtInVar = nullptr;
+ if (redeclaredBuiltIn)
+ {
+ builtInVar = &redeclaredBuiltIn->variable();
+ }
+ else
+ {
+ // User defined not found, find in built-in table
+ builtInVar = static_cast<const TVariable *>(
+ symbolTable->findBuiltIn(name, compiler->getShaderVersion()));
+ }
+ if (!builtInVar)
+ {
+ return false;
+ }
+
+ ReplaceClipCullDistanceAssignments replacementUtils(compiler, root, symbolTable, builtInVar,
+ redeclaredBuiltIn,
+ ImmutableString(replacementName));
+
+ // Declare a global variable substituting gl_ClipDistance
+ unsigned int enabledClipDistances =
+ replacementUtils.getEnabledClipCullDistance(useNonConstIndex, maxConstIndex);
+ if (!enabledClipDistances)
+ {
+ // Spec :
+ // The gl_ClipDistance array is predeclared as unsized and must be explicitly sized by the
+ // shader either redeclaring it with a size or implicitly sized by indexing it only with
+ // integral constant expressions.
+ return false;
+ }
+
+ const TVariable *replacementVar = replacementUtils.declareANGLEVariable(builtInVar);
+
+ // Replace gl_ClipDistance reference with ANGLEClipDistance, except the declaration
+ ReplaceVariableExceptOneTraverser replaceTraverser(builtInVar,
+ new TIntermSymbol(replacementVar),
+ /** exception */ redeclaredBuiltIn);
+ root->traverse(&replaceTraverser);
+ if (!replaceTraverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ // Read gl_ClipDistance to ANGLEClipDistance for getting a original data
+ if (!replacementUtils.assignOriginalValueToANGLEVariable(shaderType))
+ {
+ return false;
+ }
+
+ // Reassign ANGLEClipDistance to gl_ClipDistance but ignore those that are disabled
+ const bool isRedeclared = redeclaredBuiltIn != nullptr;
+ if (!replacementUtils.assignANGLEValueToOriginalVariable(
+ shaderType, isRedeclared, clipDistanceEnableFlags, &constIndices))
+ {
+ return false;
+ }
+
+ // If not redeclared, replace the built-in with one that is appropriately sized
+ if (!isRedeclared)
+ {
+ TType *resizedType = new TType(builtInVar->getType());
+ resizedType->setArraySize(0, enabledClipDistances);
+
+ TVariable *resizedVar = new TVariable(symbolTable, name, resizedType, SymbolType::BuiltIn);
+
+ return ReplaceVariable(compiler, root, builtInVar, resizedVar);
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+[[nodiscard]] bool ReplaceClipDistanceAssignments(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const GLenum shaderType,
+ const TIntermTyped *clipDistanceEnableFlags)
+{
+ return ReplaceClipCullDistanceAssignmentsImpl(compiler, root, symbolTable, shaderType,
+ clipDistanceEnableFlags, "gl_ClipDistance",
+ "ANGLEClipDistance", EvqClipDistance);
+}
+
+[[nodiscard]] bool ReplaceCullDistanceAssignments(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const GLenum shaderType)
+{
+ return ReplaceClipCullDistanceAssignmentsImpl(compiler, root, symbolTable, shaderType, nullptr,
+ "gl_CullDistance", "ANGLECullDistance",
+ EvqCullDistance);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.h b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.h
new file mode 100644
index 0000000000..93d19f9fe2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.h
@@ -0,0 +1,43 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ReplaceClipCullDistanceVariable.h: Find any references to gl_ClipDistance or gl_CullDistance and
+// replace it with ANGLEClipDistance or ANGLECullDistance.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_REPLACECLIPCULLDISTANCEVARIABLE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_REPLACECLIPCULLDISTANCEVARIABLE_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+struct InterfaceBlock;
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+class TIntermTyped;
+
+// Replace every gl_ClipDistance assignment with assignment to "ANGLEClipDistance",
+// then at the end of shader re-assign the values of this global variable to gl_ClipDistance.
+// This to solve some complex usages such as user passing gl_ClipDistance as output reference
+// to a function.
+// Furthermore, at the end shader, some disabled gl_ClipDistance[i] can be skipped from the
+// assignment.
+[[nodiscard]] bool ReplaceClipDistanceAssignments(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const GLenum shaderType,
+ const TIntermTyped *clipDistanceEnableFlags);
+
+[[nodiscard]] bool ReplaceCullDistanceAssignments(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const GLenum shaderType);
+} // namespace sh
+
+#endif
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.cpp
new file mode 100644
index 0000000000..47842eaade
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.cpp
@@ -0,0 +1,142 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ReplaceShadowingVariables.cpp: Replace all references to any variable in the AST that is
+// a redefinition of a variable in a nested scope. This is a useful for ESSL 1.00 shaders
+// where the spec section "4.2.3. Redeclaring Variables" states "However, a nested scope can
+// override an outer scope's declaration of a particular variable name." This is changed in
+// later spec versions, such as ESSL 3.20 spec which states "If [a variable] is declared as
+// a parameter in a function definition, it is scoped until the end of that function
+// definition. A function's parameter declarations and body together form a single scope."
+//
+// So this class is useful when translating from ESSL 1.00 shaders, where function body var
+// redefinition is allowed, to later shader versions where it's not allowed.
+//
+
+#include "compiler/translator/tree_util/ReplaceShadowingVariables.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+#include <unordered_set>
+
+namespace sh
+{
+
+namespace
+{
+
+// Custom struct to queue up any replacements until after AST traversal
+struct DeferredReplacementBlock
+{
+ const TVariable *originalVariable; // variable to be replaced
+ TVariable *replacementVariable; // variable to replace originalVar with
+ TIntermBlock *functionBody; // function body where replacement occurs
+};
+
+class ReplaceShadowingVariablesTraverser : public TIntermTraverser
+{
+ public:
+ ReplaceShadowingVariablesTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, true, true, symbolTable), mParameterNames{}, mFunctionBody(nullptr)
+ {}
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ // In pre-visit of function, record params
+ if (visit == PreVisit)
+ {
+ ASSERT(mParameterNames.size() == 0);
+ const TFunction *func = node->getFunctionPrototype()->getFunction();
+ // Grab all of the parameter names from the function prototype
+ size_t paramCount = func->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ mParameterNames.emplace(std::string(func->getParam(i)->name().data()));
+ }
+ if (mParameterNames.size() > 0)
+ mFunctionBody = node->getBody();
+ }
+ else if (visit == PostVisit)
+ {
+ // Clear data saved from function definition
+ mParameterNames.clear();
+ mFunctionBody = nullptr;
+ }
+ return true;
+ }
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ if (visit == PreVisit && mParameterNames.size() != 0)
+ {
+ TIntermSequence *decls = node->getSequence();
+ for (auto &declVector : *decls)
+ {
+ // no init case
+ TIntermSymbol *symNode = declVector->getAsSymbolNode();
+ if (symNode == nullptr)
+ {
+ // init case
+ TIntermBinary *binaryNode = declVector->getAsBinaryNode();
+ ASSERT(binaryNode->getOp() == EOpInitialize);
+ symNode = binaryNode->getLeft()->getAsSymbolNode();
+ }
+ ASSERT(symNode != nullptr);
+ std::string varName = std::string(symNode->variable().name().data());
+ if (mParameterNames.count(varName) > 0)
+ {
+ // We found a redefined var so queue replacement
+ mReplacements.emplace_back(DeferredReplacementBlock{
+ &symNode->variable(),
+ CreateTempVariable(mSymbolTable, &symNode->variable().getType()),
+ mFunctionBody});
+ }
+ }
+ }
+ return true;
+ }
+ // Perform replacement of vars for any deferred replacements that were identified
+ [[nodiscard]] bool executeReplacements(TCompiler *compiler)
+ {
+ for (DeferredReplacementBlock &replace : mReplacements)
+ {
+ if (!ReplaceVariable(compiler, replace.functionBody, replace.originalVariable,
+ replace.replacementVariable))
+ {
+ return false;
+ }
+ }
+ mReplacements.clear();
+ return true;
+ }
+
+ private:
+ std::unordered_set<std::string> mParameterNames;
+ TIntermBlock *mFunctionBody;
+ std::vector<DeferredReplacementBlock> mReplacements;
+};
+
+} // anonymous namespace
+
+// Replaces every occurrence of a variable with another variable.
+[[nodiscard]] bool ReplaceShadowingVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ ReplaceShadowingVariablesTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ if (!traverser.executeReplacements(compiler))
+ {
+ return false;
+ }
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.h b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.h
new file mode 100644
index 0000000000..f6da350f5f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.h
@@ -0,0 +1,26 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ReplaceShadowingVariables.h: Find any variables that are redefined within a nested
+// scope and replace them with a newly named variable.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_REPLACESHADOWINGVARIABLES_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_REPLACESHADOWINGVARIABLES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool ReplaceShadowingVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_REPLACESHADOWINGVARIABLES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp
new file mode 100644
index 0000000000..697cfe6c74
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp
@@ -0,0 +1,145 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ReplaceVariable.cpp: Replace all references to a specific variable in the AST with references to
+// another variable.
+
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class ReplaceVariableTraverser : public TIntermTraverser
+{
+ public:
+ ReplaceVariableTraverser(const TVariable *toBeReplaced, const TIntermTyped *replacement)
+ : TIntermTraverser(true, false, false),
+ mToBeReplaced(toBeReplaced),
+ mReplacement(replacement)
+ {}
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == mToBeReplaced)
+ {
+ queueReplacement(mReplacement->deepCopy(), OriginalNode::IS_DROPPED);
+ }
+ }
+
+ private:
+ const TVariable *const mToBeReplaced;
+ const TIntermTyped *const mReplacement;
+};
+
+class ReplaceVariablesTraverser : public TIntermTraverser
+{
+ public:
+ ReplaceVariablesTraverser(const VariableReplacementMap &variableMap)
+ : TIntermTraverser(true, false, false), mVariableMap(variableMap)
+ {}
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ auto iter = mVariableMap.find(&node->variable());
+ if (iter != mVariableMap.end())
+ {
+ queueReplacement(iter->second->deepCopy(), OriginalNode::IS_DROPPED);
+ }
+ }
+
+ private:
+ const VariableReplacementMap &mVariableMap;
+};
+
+class GetDeclaratorReplacementsTraverser : public TIntermTraverser
+{
+ public:
+ GetDeclaratorReplacementsTraverser(TSymbolTable *symbolTable,
+ VariableReplacementMap *variableMap)
+ : TIntermTraverser(true, false, false, symbolTable), mVariableMap(variableMap)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ for (TIntermNode *decl : sequence)
+ {
+ TIntermSymbol *asSymbol = decl->getAsSymbolNode();
+ TIntermBinary *asBinary = decl->getAsBinaryNode();
+
+ if (asBinary != nullptr)
+ {
+ ASSERT(asBinary->getOp() == EOpInitialize);
+ asSymbol = asBinary->getLeft()->getAsSymbolNode();
+ }
+
+ ASSERT(asSymbol);
+ const TVariable &variable = asSymbol->variable();
+
+ ASSERT(mVariableMap->find(&variable) == mVariableMap->end());
+
+ const TVariable *replacementVariable = new TVariable(
+ mSymbolTable, variable.name(), &variable.getType(), variable.symbolType());
+
+ (*mVariableMap)[&variable] = new TIntermSymbol(replacementVariable);
+ }
+
+ return false;
+ }
+
+ private:
+ VariableReplacementMap *mVariableMap;
+};
+
+} // anonymous namespace
+
+// Replaces every occurrence of a variable with another variable.
+[[nodiscard]] bool ReplaceVariable(TCompiler *compiler,
+ TIntermBlock *root,
+ const TVariable *toBeReplaced,
+ const TVariable *replacement)
+{
+ ReplaceVariableTraverser traverser(toBeReplaced, new TIntermSymbol(replacement));
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+[[nodiscard]] bool ReplaceVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ const VariableReplacementMap &variableMap)
+{
+ ReplaceVariablesTraverser traverser(variableMap);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+void GetDeclaratorReplacements(TSymbolTable *symbolTable,
+ TIntermBlock *root,
+ VariableReplacementMap *variableMap)
+{
+ GetDeclaratorReplacementsTraverser traverser(symbolTable, variableMap);
+ root->traverse(&traverser);
+}
+
+// Replaces every occurrence of a variable with a TIntermNode.
+[[nodiscard]] bool ReplaceVariableWithTyped(TCompiler *compiler,
+ TIntermBlock *root,
+ const TVariable *toBeReplaced,
+ const TIntermTyped *replacement)
+{
+ ReplaceVariableTraverser traverser(toBeReplaced, replacement);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.h b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.h
new file mode 100644
index 0000000000..e96bbc7a82
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.h
@@ -0,0 +1,48 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ReplaceVariable.h: Replace all references to a specific variable in the AST with references to
+// another variable.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_REPLACEVARIABLE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_REPLACEVARIABLE_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TIntermTyped;
+class TSymbolTable;
+class TVariable;
+
+[[nodiscard]] bool ReplaceVariable(TCompiler *compiler,
+ TIntermBlock *root,
+ const TVariable *toBeReplaced,
+ const TVariable *replacement);
+[[nodiscard]] bool ReplaceVariableWithTyped(TCompiler *compiler,
+ TIntermBlock *root,
+ const TVariable *toBeReplaced,
+ const TIntermTyped *replacement);
+
+using VariableReplacementMap = angle::HashMap<const TVariable *, const TIntermTyped *>;
+
+// Replace a set of variables with their corresponding expression.
+[[nodiscard]] bool ReplaceVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ const VariableReplacementMap &variableMap);
+
+// Find all declarators, and replace the TVariable they are declaring with a duplicate. This is
+// used to support deepCopy of TIntermBlock and TIntermLoop nodes that include declarations.
+// Replacements already present in variableMap are preserved.
+void GetDeclaratorReplacements(TSymbolTable *symbolTable,
+ TIntermBlock *root,
+ VariableReplacementMap *variableMap);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_REPLACEVARIABLE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.cpp
new file mode 100644
index 0000000000..a81d230492
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.cpp
@@ -0,0 +1,198 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteSampleMaskVariable.cpp: Find any references to gl_SampleMask and gl_SampleMaskIn, and
+// rewrite it with ANGLESampleMask or ANGLESampleMaskIn.
+//
+
+#include "compiler/translator/tree_util/RewriteSampleMaskVariable.h"
+
+#include "common/bitset_utils.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+namespace sh
+{
+namespace
+{
+constexpr int kMaxIndexForSampleMaskVar = 0;
+constexpr int kFullSampleMask = 0xFFFFFFFF;
+
+// Traverse the tree and collect the redeclaration and replace all non constant index references of
+// gl_SampleMask or gl_SampleMaskIn with constant index references
+class GLSampleMaskRelatedReferenceTraverser : public TIntermTraverser
+{
+ public:
+ GLSampleMaskRelatedReferenceTraverser(const TIntermSymbol **redeclaredSymOut,
+ const ImmutableString &targetStr)
+ : TIntermTraverser(true, false, false),
+ mRedeclaredSym(redeclaredSymOut),
+ mTargetStr(targetStr)
+ {
+ *mRedeclaredSym = nullptr;
+ }
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ // If gl_SampleMask is redeclared, we need to collect its information
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ if (sequence.size() != 1)
+ {
+ return true;
+ }
+
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ TIntermSymbol *symbol = variable->getAsSymbolNode();
+ if (symbol == nullptr || symbol->getName() != mTargetStr)
+ {
+ return true;
+ }
+
+ *mRedeclaredSym = symbol;
+
+ return true;
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TOperator op = node->getOp();
+ if (op != EOpIndexDirect && op != EOpIndexIndirect)
+ {
+ return true;
+ }
+ TIntermSymbol *left = node->getLeft()->getAsSymbolNode();
+ if (!left)
+ {
+ return true;
+ }
+ if (left->getName() != mTargetStr)
+ {
+ return true;
+ }
+ const TConstantUnion *constIdx = node->getRight()->getConstantValue();
+ if (!constIdx)
+ {
+ if (node->getRight()->hasSideEffects())
+ {
+ insertStatementInParentBlock(node->getRight());
+ }
+
+ queueReplacementWithParent(node, node->getRight(),
+ CreateIndexNode(kMaxIndexForSampleMaskVar),
+ OriginalNode::IS_DROPPED);
+ }
+
+ return true;
+ }
+
+ private:
+ const TIntermSymbol **mRedeclaredSym;
+ const ImmutableString mTargetStr;
+};
+
+} // anonymous namespace
+
+[[nodiscard]] bool RewriteSampleMask(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TIntermTyped *numSamplesUniform)
+{
+ const TIntermSymbol *redeclaredGLSampleMask = nullptr;
+ GLSampleMaskRelatedReferenceTraverser indexTraverser(&redeclaredGLSampleMask,
+ ImmutableString("gl_SampleMask"));
+
+ root->traverse(&indexTraverser);
+ if (!indexTraverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ // Retrieve gl_SampleMask variable reference
+ // Search user redeclared it first
+ const TVariable *glSampleMaskVar = nullptr;
+ if (redeclaredGLSampleMask)
+ {
+ glSampleMaskVar = &redeclaredGLSampleMask->variable();
+ }
+ else
+ {
+ // User defined not found, find in built-in table
+ glSampleMaskVar = static_cast<const TVariable *>(symbolTable->findBuiltIn(
+ ImmutableString("gl_SampleMask"), compiler->getShaderVersion()));
+ }
+ if (!glSampleMaskVar)
+ {
+ return false;
+ }
+
+ // Current ANGLE assumes that the maximum number of samples is less than or equal to
+ // VK_SAMPLE_COUNT_32_BIT. So, the size of gl_SampleMask array is always one.
+ const unsigned int arraySizeOfSampleMask = glSampleMaskVar->getType().getOutermostArraySize();
+ ASSERT(arraySizeOfSampleMask == 1);
+
+ TIntermSymbol *glSampleMaskSymbol = new TIntermSymbol(glSampleMaskVar);
+
+ // if (ANGLEUniforms.numSamples == 1)
+ // {
+ // gl_SampleMask[0] = int(0xFFFFFFFF);
+ // }
+ TIntermConstantUnion *singleSampleCount = CreateUIntNode(1);
+ TIntermBinary *equalTo =
+ new TIntermBinary(EOpEqual, numSamplesUniform->deepCopy(), singleSampleCount);
+
+ TIntermBlock *trueBlock = new TIntermBlock();
+
+ TIntermBinary *sampleMaskVar = new TIntermBinary(EOpIndexDirect, glSampleMaskSymbol->deepCopy(),
+ CreateIndexNode(kMaxIndexForSampleMaskVar));
+ TIntermConstantUnion *fullSampleMask = CreateIndexNode(kFullSampleMask);
+ TIntermBinary *assignment = new TIntermBinary(EOpAssign, sampleMaskVar, fullSampleMask);
+
+ trueBlock->appendStatement(assignment);
+
+ TIntermIfElse *multiSampleOrNot = new TIntermIfElse(equalTo, trueBlock, nullptr);
+
+ return RunAtTheEndOfShader(compiler, root, multiSampleOrNot, symbolTable);
+}
+
+[[nodiscard]] bool RewriteSampleMaskIn(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ const TIntermSymbol *redeclaredGLSampleMaskIn = nullptr;
+ GLSampleMaskRelatedReferenceTraverser indexTraverser(&redeclaredGLSampleMaskIn,
+ ImmutableString("gl_SampleMaskIn"));
+
+ root->traverse(&indexTraverser);
+ if (!indexTraverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ // Retrieve gl_SampleMaskIn variable reference
+ const TVariable *glSampleMaskInVar = nullptr;
+ glSampleMaskInVar = static_cast<const TVariable *>(
+ symbolTable->findBuiltIn(ImmutableString("gl_SampleMaskIn"), compiler->getShaderVersion()));
+ if (!glSampleMaskInVar)
+ {
+ return false;
+ }
+
+ // Current ANGLE assumes that the maximum number of samples is less than or equal to
+ // VK_SAMPLE_COUNT_32_BIT. So, the size of gl_SampleMask array is always one.
+ const unsigned int arraySizeOfSampleMaskIn =
+ glSampleMaskInVar->getType().getOutermostArraySize();
+ ASSERT(arraySizeOfSampleMaskIn == 1);
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.h b/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.h
new file mode 100644
index 0000000000..20f19313b2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteSampleMaskVariable.cpp: Find any references to gl_SampleMask and gl_SampleMaskIn, and
+// rewrite it with ANGLESampleMask or ANGLESampleMaskIn.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_REWRITESAMPLEMASKVARIABLE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_REWRITESAMPLEMASKVARIABLE_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+class TIntermTyped;
+
+// Rewrite every gl_SampleMask or gl_SampleMaskIn to "ANGLESampleMask" or "ANGLESampleMaskIn", then
+// at the end of shader re-assign the values of this global variable to gl_SampleMask and
+// gl_SampleMaskIn. This to solve the problem which the non constant index is used for the unsized
+// array problem.
+[[nodiscard]] bool RewriteSampleMask(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TIntermTyped *numSamplesUniform);
+
+[[nodiscard]] bool RewriteSampleMaskIn(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_REWRITESAMPLEMASKVARIABLE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.cpp
new file mode 100644
index 0000000000..99be6add13
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.cpp
@@ -0,0 +1,35 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RunAtTheBeginningOfShader.cpp: Add code to be run at the beginning of the shader.
+// void main() { body }
+// =>
+// void main()
+// {
+// codeToRun
+// body
+// }
+//
+
+#include "compiler/translator/tree_util/RunAtTheBeginningOfShader.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+bool RunAtTheBeginningOfShader(TCompiler *compiler, TIntermBlock *root, TIntermNode *codeToRun)
+{
+ TIntermFunctionDefinition *main = FindMain(root);
+ main->getBody()->insertStatement(0, codeToRun);
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.h b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.h
new file mode 100644
index 0000000000..23ed9f9372
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RunAtTheBeginningOfShader.h: Add code to be run at the beginning of the shader.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEBEGINNINGOFSHADER_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEBEGINNINGOFSHADER_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TIntermNode;
+
+[[nodiscard]] bool RunAtTheBeginningOfShader(TCompiler *compiler,
+ TIntermBlock *root,
+ TIntermNode *codeToRun);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEBEGINNINGOFSHADER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp
new file mode 100644
index 0000000000..daf99185ab
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp
@@ -0,0 +1,129 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RunAtTheEndOfShader.cpp: Add code to be run at the end of the shader. In case main() contains a
+// return statement, this is done by replacing the main() function with another function that calls
+// the old main, like this:
+//
+// void main() { body }
+// =>
+// void main0() { body }
+// void main()
+// {
+// main0();
+// codeToRun
+// }
+//
+// This way the code will get run even if the return statement inside main is executed.
+//
+// This is done if main ends in an unconditional |discard| as well, to help with SPIR-V generation
+// that expects no dead-code to be present after branches in a block. To avoid bugs when |discard|
+// is wrapped in unconditional blocks, any |discard| in main() is used as a signal to wrap it.
+//
+
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kMainString("main");
+
+class ContainsReturnOrDiscardTraverser : public TIntermTraverser
+{
+ public:
+ ContainsReturnOrDiscardTraverser()
+ : TIntermTraverser(true, false, false), mContainsReturnOrDiscard(false)
+ {}
+
+ bool visitBranch(Visit visit, TIntermBranch *node) override
+ {
+ if (node->getFlowOp() == EOpReturn || node->getFlowOp() == EOpKill)
+ {
+ mContainsReturnOrDiscard = true;
+ }
+ return false;
+ }
+
+ bool containsReturnOrDiscard() { return mContainsReturnOrDiscard; }
+
+ private:
+ bool mContainsReturnOrDiscard;
+};
+
+bool ContainsReturnOrDiscard(TIntermNode *node)
+{
+ ContainsReturnOrDiscardTraverser traverser;
+ node->traverse(&traverser);
+ return traverser.containsReturnOrDiscard();
+}
+
+void WrapMainAndAppend(TIntermBlock *root,
+ TIntermFunctionDefinition *main,
+ TIntermNode *codeToRun,
+ TSymbolTable *symbolTable)
+{
+ // Replace main() with main0() with the same body.
+ TFunction *oldMain =
+ new TFunction(symbolTable, kEmptyImmutableString, SymbolType::AngleInternal,
+ StaticType::GetBasic<EbtVoid, EbpUndefined>(), false);
+ TIntermFunctionDefinition *oldMainDefinition =
+ CreateInternalFunctionDefinitionNode(*oldMain, main->getBody());
+
+ bool replaced = root->replaceChildNode(main, oldMainDefinition);
+ ASSERT(replaced);
+
+ // void main()
+ TFunction *newMain = new TFunction(symbolTable, kMainString, SymbolType::UserDefined,
+ StaticType::GetBasic<EbtVoid, EbpUndefined>(), false);
+ TIntermFunctionPrototype *newMainProto = new TIntermFunctionPrototype(newMain);
+
+ // {
+ // main0();
+ // codeToRun
+ // }
+ TIntermBlock *newMainBody = new TIntermBlock();
+ TIntermSequence emptySequence;
+ TIntermAggregate *oldMainCall = TIntermAggregate::CreateFunctionCall(*oldMain, &emptySequence);
+ newMainBody->appendStatement(oldMainCall);
+ newMainBody->appendStatement(codeToRun);
+
+ // Add the new main() to the root node.
+ TIntermFunctionDefinition *newMainDefinition =
+ new TIntermFunctionDefinition(newMainProto, newMainBody);
+ root->appendStatement(newMainDefinition);
+}
+
+} // anonymous namespace
+
+bool RunAtTheEndOfShader(TCompiler *compiler,
+ TIntermBlock *root,
+ TIntermNode *codeToRun,
+ TSymbolTable *symbolTable)
+{
+ TIntermFunctionDefinition *main = FindMain(root);
+ if (ContainsReturnOrDiscard(main))
+ {
+ WrapMainAndAppend(root, main, codeToRun, symbolTable);
+ }
+ else
+ {
+ main->getBody()->appendStatement(codeToRun);
+ }
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.h b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.h
new file mode 100644
index 0000000000..cfa5fb1fab
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RunAtTheEndOfShader.h: Add code to be run at the end of the shader.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEENDOFSHADER_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEENDOFSHADER_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RunAtTheEndOfShader(TCompiler *compiler,
+ TIntermBlock *root,
+ TIntermNode *codeToRun,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEENDOFSHADER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.cpp
new file mode 100644
index 0000000000..6a7254802c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.cpp
@@ -0,0 +1,122 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SpecializationConst.cpp: Add code to generate AST node for various specialization constants.
+//
+
+#include "compiler/translator/tree_util/SpecializationConstant.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+
+namespace sh
+{
+
+namespace
+{
+// Specialization constant names
+constexpr ImmutableString kSurfaceRotationSpecConstVarName =
+ ImmutableString("ANGLESurfaceRotation");
+constexpr ImmutableString kDitherSpecConstVarName = ImmutableString("ANGLEDither");
+
+const TType *MakeSpecConst(const TType &type, vk::SpecializationConstantId id)
+{
+ // Create a new type with the EvqSpecConst qualifier
+ TType *specConstType = new TType(type);
+ specConstType->setQualifier(EvqSpecConst);
+
+ // Set the constant_id of the spec const
+ TLayoutQualifier layoutQualifier = TLayoutQualifier::Create();
+ layoutQualifier.location = static_cast<int>(id);
+ specConstType->setLayoutQualifier(layoutQualifier);
+
+ return specConstType;
+}
+} // anonymous namespace
+
+SpecConst::SpecConst(TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ GLenum shaderType)
+ : mSymbolTable(symbolTable),
+ mCompileOptions(compileOptions),
+ mSurfaceRotationVar(nullptr),
+ mDitherVar(nullptr)
+{
+ if (shaderType == GL_FRAGMENT_SHADER || shaderType == GL_COMPUTE_SHADER)
+ {
+ return;
+ }
+
+ // Mark SpecConstUsage::Rotation unconditionally. gl_Position is always rotated.
+ if (mCompileOptions.useSpecializationConstant)
+ {
+ mUsageBits.set(vk::SpecConstUsage::Rotation);
+ }
+}
+
+SpecConst::~SpecConst() {}
+
+void SpecConst::declareSpecConsts(TIntermBlock *root)
+{
+ // Add specialization constant declarations. The default value of the specialization
+ // constant is irrelevant, as it will be set when creating the pipeline.
+ // Only emit specialized const declaration if it has been referenced.
+ if (mSurfaceRotationVar != nullptr)
+ {
+ TIntermDeclaration *decl = new TIntermDeclaration();
+ decl->appendDeclarator(
+ new TIntermBinary(EOpInitialize, getRotation(), CreateBoolNode(false)));
+
+ root->insertStatement(0, decl);
+ }
+
+ if (mDitherVar != nullptr)
+ {
+ TIntermDeclaration *decl = new TIntermDeclaration();
+ decl->appendDeclarator(new TIntermBinary(EOpInitialize, getDither(), CreateUIntNode(0)));
+
+ root->insertStatement(0, decl);
+ }
+}
+
+TIntermSymbol *SpecConst::getRotation()
+{
+ if (mSurfaceRotationVar == nullptr)
+ {
+ const TType *type = MakeSpecConst(*StaticType::GetBasic<EbtBool, EbpUndefined>(),
+ vk::SpecializationConstantId::SurfaceRotation);
+
+ mSurfaceRotationVar = new TVariable(mSymbolTable, kSurfaceRotationSpecConstVarName, type,
+ SymbolType::AngleInternal);
+ }
+ return new TIntermSymbol(mSurfaceRotationVar);
+}
+
+TIntermTyped *SpecConst::getSwapXY()
+{
+ if (!mCompileOptions.useSpecializationConstant)
+ {
+ return nullptr;
+ }
+ mUsageBits.set(vk::SpecConstUsage::Rotation);
+ return getRotation();
+}
+
+TIntermTyped *SpecConst::getDither()
+{
+ if (mDitherVar == nullptr)
+ {
+ const TType *type = MakeSpecConst(*StaticType::GetBasic<EbtUInt, EbpHigh>(),
+ vk::SpecializationConstantId::Dither);
+
+ mDitherVar =
+ new TVariable(mSymbolTable, kDitherSpecConstVarName, type, SymbolType::AngleInternal);
+ mUsageBits.set(vk::SpecConstUsage::Dither);
+ }
+ return new TIntermSymbol(mDitherVar);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.h b/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.h
new file mode 100644
index 0000000000..6644706567
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.h
@@ -0,0 +1,55 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SpecializationConst.h: Add code to generate AST node for specialization constant.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_SPECIALIZATIONCONSTANT_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_SPECIALIZATIONCONSTANT_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+
+class TIntermBlock;
+class TIntermTyped;
+class TIntermSymbol;
+class TVariable;
+
+namespace sh
+{
+
+class SpecConst
+{
+ public:
+ SpecConst(TSymbolTable *symbolTable, const ShCompileOptions &compileOptions, GLenum shaderType);
+ virtual ~SpecConst();
+
+ // Flip/rotation
+ // Returns a boolean: should X and Y be swapped?
+ TIntermTyped *getSwapXY();
+
+ // Dither emulation
+ TIntermTyped *getDither();
+
+ void declareSpecConsts(TIntermBlock *root);
+ SpecConstUsageBits getSpecConstUsageBits() const { return mUsageBits; }
+
+ private:
+ TIntermSymbol *getRotation();
+
+ // If unsupported, this should be set to null.
+ TSymbolTable *mSymbolTable;
+ const ShCompileOptions &mCompileOptions;
+
+ TVariable *mSurfaceRotationVar;
+ TVariable *mDitherVar;
+
+ // Bit is set if YFlip or Rotation has been used
+ SpecConstUsageBits mUsageBits;
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_SPECIALIZATIONCONSTANT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/Visit.h b/gfx/angle/checkout/src/compiler/translator/tree_util/Visit.h
new file mode 100644
index 0000000000..36a8f14a52
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/Visit.h
@@ -0,0 +1,22 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_VISIT_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_VISIT_H_
+
+namespace sh
+{
+
+enum Visit
+{
+ PreVisit,
+ InVisit,
+ PostVisit
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_VISIT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/util.cpp b/gfx/angle/checkout/src/compiler/translator/util.cpp
new file mode 100644
index 0000000000..f1dd8c2fb3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/util.cpp
@@ -0,0 +1,1023 @@
+//
+// Copyright 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/util.h"
+
+#include <limits>
+
+#include "common/utilities.h"
+#include "compiler/preprocessor/numeric_lex.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+
+bool atoi_clamp(const char *str, unsigned int *value)
+{
+ bool success = angle::pp::numeric_lex_int(str, value);
+ if (!success)
+ *value = std::numeric_limits<unsigned int>::max();
+ return success;
+}
+
+namespace sh
+{
+
+namespace
+{
+// [primarySize-1][secondarySize-1] is the GL type with a basic type of float.
+constexpr GLenum kFloatGLType[4][4] = {
+ // float1xS only makes sense for S == 1
+ {
+ GL_FLOAT,
+ GL_NONE,
+ GL_NONE,
+ GL_NONE,
+ },
+ // float2xS is vec2 for S == 1, and mat2xS o.w.
+ {
+ GL_FLOAT_VEC2,
+ GL_FLOAT_MAT2,
+ GL_FLOAT_MAT2x3,
+ GL_FLOAT_MAT2x4,
+ },
+ // float3xS is vec3 for S == 1, and mat3xS o.w.
+ {
+ GL_FLOAT_VEC3,
+ GL_FLOAT_MAT3x2,
+ GL_FLOAT_MAT3,
+ GL_FLOAT_MAT3x4,
+ },
+ // float4xS is vec4 for S == 1, and mat4xS o.w.
+ {
+ GL_FLOAT_VEC4,
+ GL_FLOAT_MAT4x2,
+ GL_FLOAT_MAT4x3,
+ GL_FLOAT_MAT4,
+ },
+};
+// [primarySize-1] is the GL type with a basic type of int.
+constexpr GLenum kIntGLType[4] = {GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4};
+// [primarySize-1] is the GL type with a basic type of uint.
+constexpr GLenum kUIntGLType[4] = {GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
+ GL_UNSIGNED_INT_VEC4};
+// [primarySize-1] is the GL type with a basic type of bool.
+constexpr GLenum kBoolGLType[4] = {GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4};
+
+bool IsInterpolationIn(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqSmoothIn:
+ case EvqFlatIn:
+ case EvqNoPerspectiveIn:
+ case EvqCentroidIn:
+ case EvqSampleIn:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsInterpolationOut(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqSmoothOut:
+ case EvqFlatOut:
+ case EvqNoPerspectiveOut:
+ case EvqCentroidOut:
+ case EvqSampleOut:
+ return true;
+ default:
+ return false;
+ }
+}
+} // anonymous namespace
+
+float NumericLexFloat32OutOfRangeToInfinity(const std::string &str)
+{
+ // Parses a decimal string using scientific notation into a floating point number.
+ // Out-of-range values are converted to infinity. Values that are too small to be
+ // represented are converted to zero.
+
+ // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not
+ // matter.
+ unsigned int decimalMantissa = 0;
+ size_t i = 0;
+ bool decimalPointSeen = false;
+ bool nonZeroSeenInMantissa = false;
+
+ // The exponent offset reflects the position of the decimal point.
+ int exponentOffset = -1;
+
+ // This is just a counter for how many decimal digits are written to decimalMantissa.
+ int mantissaDecimalDigits = 0;
+
+ while (i < str.length())
+ {
+ const char c = str[i];
+ if (c == 'e' || c == 'E')
+ {
+ break;
+ }
+ if (c == '.')
+ {
+ decimalPointSeen = true;
+ ++i;
+ continue;
+ }
+
+ unsigned int digit = static_cast<unsigned int>(c - '0');
+ ASSERT(digit < 10u);
+ if (digit != 0u)
+ {
+ nonZeroSeenInMantissa = true;
+ }
+ if (nonZeroSeenInMantissa)
+ {
+ // Add bits to the mantissa until space runs out in 32-bit int. This should be
+ // enough precision to make the resulting binary mantissa accurate to 1 ULP.
+ if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u)
+ {
+ decimalMantissa = decimalMantissa * 10u + digit;
+ ++mantissaDecimalDigits;
+ }
+ if (!decimalPointSeen)
+ {
+ ++exponentOffset;
+ }
+ }
+ else if (decimalPointSeen)
+ {
+ --exponentOffset;
+ }
+ ++i;
+ }
+ if (decimalMantissa == 0)
+ {
+ return 0.0f;
+ }
+ int exponent = 0;
+ if (i < str.length())
+ {
+ ASSERT(str[i] == 'e' || str[i] == 'E');
+ ++i;
+ bool exponentOutOfRange = false;
+ bool negativeExponent = false;
+ if (str[i] == '-')
+ {
+ negativeExponent = true;
+ ++i;
+ }
+ else if (str[i] == '+')
+ {
+ ++i;
+ }
+ while (i < str.length())
+ {
+ const char c = str[i];
+ unsigned int digit = static_cast<unsigned int>(c - '0');
+ ASSERT(digit < 10u);
+ if (exponent <= (std::numeric_limits<int>::max() - 9) / 10)
+ {
+ exponent = exponent * 10 + digit;
+ }
+ else
+ {
+ exponentOutOfRange = true;
+ }
+ ++i;
+ }
+ if (negativeExponent)
+ {
+ exponent = -exponent;
+ }
+ if (exponentOutOfRange)
+ {
+ if (negativeExponent)
+ {
+ return 0.0f;
+ }
+ else
+ {
+ return std::numeric_limits<float>::infinity();
+ }
+ }
+ }
+ // Do the calculation in 64-bit to avoid overflow.
+ long long exponentLong =
+ static_cast<long long>(exponent) + static_cast<long long>(exponentOffset);
+ if (exponentLong > std::numeric_limits<float>::max_exponent10)
+ {
+ return std::numeric_limits<float>::infinity();
+ }
+ else if (exponentLong < std::numeric_limits<float>::min_exponent10)
+ {
+ return 0.0f;
+ }
+ // The exponent is in range, so we need to actually evaluate the float.
+ exponent = static_cast<int>(exponentLong);
+ double value = decimalMantissa;
+
+ // Calculate the exponent offset to normalize the mantissa.
+ int normalizationExponentOffset = 1 - mantissaDecimalDigits;
+ // Apply the exponent.
+ value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset));
+ if (value > static_cast<double>(std::numeric_limits<float>::max()))
+ {
+ return std::numeric_limits<float>::infinity();
+ }
+ if (value < static_cast<double>(std::numeric_limits<float>::min()))
+ {
+ return 0.0f;
+ }
+ return static_cast<float>(value);
+}
+
+bool strtof_clamp(const std::string &str, float *value)
+{
+ // Custom float parsing that can handle the following corner cases:
+ // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting
+ // number inside the float range.
+ // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting
+ // number inside the float range.
+ // 3. The value is out-of-range and should be evaluated as infinity.
+ // 4. The value is too small and should be evaluated as zero.
+ // See ESSL 3.00.6 section 4.1.4 for the relevant specification.
+ *value = NumericLexFloat32OutOfRangeToInfinity(str);
+ return !gl::isInf(*value);
+}
+
+GLenum GLVariableType(const TType &type)
+{
+ switch (type.getBasicType())
+ {
+ case EbtFloat:
+ ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
+ ASSERT(type.getSecondarySize() >= 1 && type.getSecondarySize() <= 4);
+
+ return kFloatGLType[type.getNominalSize() - 1][type.getSecondarySize() - 1];
+
+ case EbtInt:
+ ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
+ ASSERT(type.getSecondarySize() == 1);
+
+ return kIntGLType[type.getNominalSize() - 1];
+
+ case EbtUInt:
+ ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
+ ASSERT(type.getSecondarySize() == 1);
+
+ return kUIntGLType[type.getNominalSize() - 1];
+
+ case EbtBool:
+ ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
+ ASSERT(type.getSecondarySize() == 1);
+
+ return kBoolGLType[type.getNominalSize() - 1];
+
+ case EbtSampler2D:
+ return GL_SAMPLER_2D;
+ case EbtSampler3D:
+ return GL_SAMPLER_3D;
+ case EbtSamplerCube:
+ return GL_SAMPLER_CUBE;
+ case EbtSamplerExternalOES:
+ return GL_SAMPLER_EXTERNAL_OES;
+ case EbtSamplerExternal2DY2YEXT:
+ return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
+ case EbtSampler2DRect:
+ return GL_SAMPLER_2D_RECT_ANGLE;
+ case EbtSampler2DArray:
+ return GL_SAMPLER_2D_ARRAY;
+ case EbtSampler2DMS:
+ return GL_SAMPLER_2D_MULTISAMPLE;
+ case EbtSampler2DMSArray:
+ return GL_SAMPLER_2D_MULTISAMPLE_ARRAY;
+ case EbtSamplerCubeArray:
+ return GL_SAMPLER_CUBE_MAP_ARRAY;
+ case EbtSamplerBuffer:
+ return GL_SAMPLER_BUFFER;
+ case EbtISampler2D:
+ return GL_INT_SAMPLER_2D;
+ case EbtISampler3D:
+ return GL_INT_SAMPLER_3D;
+ case EbtISamplerCube:
+ return GL_INT_SAMPLER_CUBE;
+ case EbtISampler2DArray:
+ return GL_INT_SAMPLER_2D_ARRAY;
+ case EbtISampler2DMS:
+ return GL_INT_SAMPLER_2D_MULTISAMPLE;
+ case EbtISampler2DMSArray:
+ return GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
+ case EbtISamplerCubeArray:
+ return GL_INT_SAMPLER_CUBE_MAP_ARRAY;
+ case EbtISamplerBuffer:
+ return GL_INT_SAMPLER_BUFFER;
+ case EbtUSampler2D:
+ return GL_UNSIGNED_INT_SAMPLER_2D;
+ case EbtUSampler3D:
+ return GL_UNSIGNED_INT_SAMPLER_3D;
+ case EbtUSamplerCube:
+ return GL_UNSIGNED_INT_SAMPLER_CUBE;
+ case EbtUSampler2DArray:
+ return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
+ case EbtUSampler2DMS:
+ return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
+ case EbtUSampler2DMSArray:
+ return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
+ case EbtUSamplerCubeArray:
+ return GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY;
+ case EbtUSamplerBuffer:
+ return GL_UNSIGNED_INT_SAMPLER_BUFFER;
+ case EbtSampler2DShadow:
+ return GL_SAMPLER_2D_SHADOW;
+ case EbtSamplerCubeShadow:
+ return GL_SAMPLER_CUBE_SHADOW;
+ case EbtSampler2DArrayShadow:
+ return GL_SAMPLER_2D_ARRAY_SHADOW;
+ case EbtSamplerCubeArrayShadow:
+ return GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW;
+ case EbtImage2D:
+ return GL_IMAGE_2D;
+ case EbtIImage2D:
+ return GL_INT_IMAGE_2D;
+ case EbtUImage2D:
+ return GL_UNSIGNED_INT_IMAGE_2D;
+ case EbtImage2DArray:
+ return GL_IMAGE_2D_ARRAY;
+ case EbtIImage2DArray:
+ return GL_INT_IMAGE_2D_ARRAY;
+ case EbtUImage2DArray:
+ return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
+ case EbtImage3D:
+ return GL_IMAGE_3D;
+ case EbtIImage3D:
+ return GL_INT_IMAGE_3D;
+ case EbtUImage3D:
+ return GL_UNSIGNED_INT_IMAGE_3D;
+ case EbtImageCube:
+ return GL_IMAGE_CUBE;
+ case EbtIImageCube:
+ return GL_INT_IMAGE_CUBE;
+ case EbtUImageCube:
+ return GL_UNSIGNED_INT_IMAGE_CUBE;
+ case EbtImageCubeArray:
+ return GL_IMAGE_CUBE_MAP_ARRAY;
+ case EbtIImageCubeArray:
+ return GL_INT_IMAGE_CUBE_MAP_ARRAY;
+ case EbtUImageCubeArray:
+ return GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY;
+ case EbtImageBuffer:
+ return GL_IMAGE_BUFFER;
+ case EbtIImageBuffer:
+ return GL_INT_IMAGE_BUFFER;
+ case EbtUImageBuffer:
+ return GL_UNSIGNED_INT_IMAGE_BUFFER;
+ case EbtAtomicCounter:
+ return GL_UNSIGNED_INT_ATOMIC_COUNTER;
+ case EbtSamplerVideoWEBGL:
+ return GL_SAMPLER_VIDEO_IMAGE_WEBGL;
+ case EbtPixelLocalANGLE:
+ case EbtIPixelLocalANGLE:
+ case EbtUPixelLocalANGLE:
+ // TODO(anglebug.com/7279): For now, we can expect PLS handles to be rewritten to images
+ // before anyone calls into here.
+ [[fallthrough]];
+ default:
+ UNREACHABLE();
+ return GL_NONE;
+ }
+}
+
+GLenum GLVariablePrecision(const TType &type)
+{
+ if (type.getBasicType() == EbtFloat)
+ {
+ switch (type.getPrecision())
+ {
+ case EbpHigh:
+ return GL_HIGH_FLOAT;
+ case EbpMedium:
+ return GL_MEDIUM_FLOAT;
+ case EbpLow:
+ return GL_LOW_FLOAT;
+ case EbpUndefined:
+ // Desktop specs do not use precision
+ return GL_NONE;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
+ {
+ switch (type.getPrecision())
+ {
+ case EbpHigh:
+ return GL_HIGH_INT;
+ case EbpMedium:
+ return GL_MEDIUM_INT;
+ case EbpLow:
+ return GL_LOW_INT;
+ case EbpUndefined:
+ // Desktop specs do not use precision
+ return GL_NONE;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ // Other types (boolean, sampler) don't have a precision
+ return GL_NONE;
+}
+
+ImmutableString ArrayString(const TType &type)
+{
+ if (!type.isArray())
+ return ImmutableString("");
+
+ const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
+ constexpr const size_t kMaxDecimalDigitsPerSize = 10u;
+ ImmutableStringBuilder arrayString(arraySizes.size() * (kMaxDecimalDigitsPerSize + 2u));
+ for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
+ ++arraySizeIter)
+ {
+ arrayString << "[";
+ if (*arraySizeIter > 0)
+ {
+ arrayString.appendDecimal(*arraySizeIter);
+ }
+ arrayString << "]";
+ }
+ return arrayString;
+}
+
+ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
+{
+ if (type.getBasicType() == EbtStruct)
+ return HashName(type.getStruct(), hashFunction, nameMap);
+ else
+ return ImmutableString(type.getBuiltInTypeNameString());
+}
+
+bool IsVaryingOut(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqVaryingOut:
+ case EvqSmoothOut:
+ case EvqFlatOut:
+ case EvqNoPerspectiveOut:
+ case EvqCentroidOut:
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ case EvqSampleOut:
+ case EvqPatchOut:
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool IsVaryingIn(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqVaryingIn:
+ case EvqSmoothIn:
+ case EvqFlatIn:
+ case EvqNoPerspectiveIn:
+ case EvqCentroidIn:
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ case EvqSampleIn:
+ case EvqPatchIn:
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool IsVarying(TQualifier qualifier)
+{
+ return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
+}
+
+bool IsMatrixGLType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT4x3:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
+{
+ return (qualifier == EvqGeometryIn) ||
+ ((shaderType == GL_GEOMETRY_SHADER_EXT) && IsInterpolationIn(qualifier));
+}
+
+bool IsTessellationControlShaderInput(GLenum shaderType, TQualifier qualifier)
+{
+ return qualifier == EvqTessControlIn ||
+ ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationIn(qualifier));
+}
+
+bool IsTessellationControlShaderOutput(GLenum shaderType, TQualifier qualifier)
+{
+ return qualifier == EvqTessControlOut ||
+ ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationOut(qualifier));
+}
+
+bool IsTessellationEvaluationShaderInput(GLenum shaderType, TQualifier qualifier)
+{
+ return qualifier == EvqTessEvaluationIn ||
+ ((shaderType == GL_TESS_EVALUATION_SHADER) && IsInterpolationIn(qualifier));
+}
+
+InterpolationType GetInterpolationType(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqFlatIn:
+ case EvqFlatOut:
+ // The auxiliary storage qualifier patch is not used for interpolation
+ // it is a compile-time error to use interpolation qualifiers with patch
+ case EvqPatchIn:
+ case EvqPatchOut:
+ return INTERPOLATION_FLAT;
+
+ case EvqNoPerspectiveIn:
+ case EvqNoPerspectiveOut:
+ return INTERPOLATION_NOPERSPECTIVE;
+
+ case EvqSmoothIn:
+ case EvqSmoothOut:
+ case EvqVertexOut:
+ case EvqFragmentIn:
+ case EvqVaryingIn:
+ case EvqVaryingOut:
+ case EvqGeometryIn:
+ case EvqGeometryOut:
+ case EvqTessControlIn:
+ case EvqTessControlOut:
+ case EvqTessEvaluationIn:
+ case EvqTessEvaluationOut:
+ return INTERPOLATION_SMOOTH;
+
+ case EvqCentroidIn:
+ case EvqCentroidOut:
+ return INTERPOLATION_CENTROID;
+
+ case EvqSampleIn:
+ case EvqSampleOut:
+ return INTERPOLATION_SAMPLE;
+ default:
+ UNREACHABLE();
+ return INTERPOLATION_SMOOTH;
+ }
+}
+
+// a field may not have qualifer without in or out.
+InterpolationType GetFieldInterpolationType(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqFlat:
+ return INTERPOLATION_FLAT;
+ case EvqNoPerspective:
+ return INTERPOLATION_NOPERSPECTIVE;
+ case EvqSmooth:
+ return INTERPOLATION_SMOOTH;
+ case EvqCentroid:
+ return INTERPOLATION_CENTROID;
+ default:
+ return GetInterpolationType(qualifier);
+ }
+}
+
+TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
+{
+ switch (var.type)
+ {
+ case GL_BOOL:
+ return TType(EbtBool);
+ case GL_BOOL_VEC2:
+ return TType(EbtBool, 2);
+ case GL_BOOL_VEC3:
+ return TType(EbtBool, 3);
+ case GL_BOOL_VEC4:
+ return TType(EbtBool, 4);
+ case GL_FLOAT:
+ return TType(EbtFloat);
+ case GL_FLOAT_VEC2:
+ return TType(EbtFloat, 2);
+ case GL_FLOAT_VEC3:
+ return TType(EbtFloat, 3);
+ case GL_FLOAT_VEC4:
+ return TType(EbtFloat, 4);
+ case GL_FLOAT_MAT2:
+ return TType(EbtFloat, 2, 2);
+ case GL_FLOAT_MAT3:
+ return TType(EbtFloat, 3, 3);
+ case GL_FLOAT_MAT4:
+ return TType(EbtFloat, 4, 4);
+ case GL_FLOAT_MAT2x3:
+ return TType(EbtFloat, 2, 3);
+ case GL_FLOAT_MAT2x4:
+ return TType(EbtFloat, 2, 4);
+ case GL_FLOAT_MAT3x2:
+ return TType(EbtFloat, 3, 2);
+ case GL_FLOAT_MAT3x4:
+ return TType(EbtFloat, 3, 4);
+ case GL_FLOAT_MAT4x2:
+ return TType(EbtFloat, 4, 2);
+ case GL_FLOAT_MAT4x3:
+ return TType(EbtFloat, 4, 3);
+ case GL_INT:
+ return TType(EbtInt);
+ case GL_INT_VEC2:
+ return TType(EbtInt, 2);
+ case GL_INT_VEC3:
+ return TType(EbtInt, 3);
+ case GL_INT_VEC4:
+ return TType(EbtInt, 4);
+ case GL_UNSIGNED_INT:
+ return TType(EbtUInt);
+ case GL_UNSIGNED_INT_VEC2:
+ return TType(EbtUInt, 2);
+ case GL_UNSIGNED_INT_VEC3:
+ return TType(EbtUInt, 3);
+ case GL_UNSIGNED_INT_VEC4:
+ return TType(EbtUInt, 4);
+ default:
+ UNREACHABLE();
+ return TType();
+ }
+}
+
+void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
+{
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->appendDeclarator(new TIntermSymbol(variable));
+
+ TIntermSequence *globalSequence = root->getSequence();
+ globalSequence->insert(globalSequence->begin(), declaration);
+}
+
+// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
+bool CanBeInvariantESSL1(TQualifier qualifier)
+{
+ return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
+ IsBuiltinOutputVariable(qualifier) ||
+ (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
+}
+
+// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
+// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
+bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
+{
+ return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
+ IsBuiltinOutputVariable(qualifier) || qualifier == EvqFragmentInOut;
+}
+
+bool IsBuiltinOutputVariable(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqPosition:
+ case EvqPointSize:
+ case EvqFragDepth:
+ case EvqFragColor:
+ case EvqSecondaryFragColorEXT:
+ case EvqFragData:
+ case EvqSecondaryFragDataEXT:
+ case EvqClipDistance:
+ case EvqCullDistance:
+ case EvqLastFragData:
+ case EvqSampleMask:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqFragCoord:
+ case EvqPointCoord:
+ case EvqFrontFacing:
+ case EvqHelperInvocation:
+ case EvqLastFragData:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+bool IsShaderOutput(TQualifier qualifier)
+{
+ return IsVaryingOut(qualifier) || IsBuiltinOutputVariable(qualifier);
+}
+
+bool IsFragmentOutput(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqFragmentOut:
+ case EvqFragmentInOut:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsOutputESSL(ShShaderOutput output)
+{
+ return output == SH_ESSL_OUTPUT;
+}
+
+bool IsOutputGLSL(ShShaderOutput output)
+{
+ switch (output)
+ {
+ case SH_GLSL_130_OUTPUT:
+ case SH_GLSL_140_OUTPUT:
+ case SH_GLSL_150_CORE_OUTPUT:
+ case SH_GLSL_330_CORE_OUTPUT:
+ case SH_GLSL_400_CORE_OUTPUT:
+ case SH_GLSL_410_CORE_OUTPUT:
+ case SH_GLSL_420_CORE_OUTPUT:
+ case SH_GLSL_430_CORE_OUTPUT:
+ case SH_GLSL_440_CORE_OUTPUT:
+ case SH_GLSL_450_CORE_OUTPUT:
+ case SH_GLSL_COMPATIBILITY_OUTPUT:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+bool IsOutputHLSL(ShShaderOutput output)
+{
+ switch (output)
+ {
+ case SH_HLSL_3_0_OUTPUT:
+ case SH_HLSL_4_1_OUTPUT:
+ case SH_HLSL_4_0_FL9_3_OUTPUT:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+bool IsOutputVulkan(ShShaderOutput output)
+{
+ return output == SH_SPIRV_VULKAN_OUTPUT;
+}
+bool IsOutputMetal(ShShaderOutput output)
+{
+ return output == SH_SPIRV_METAL_OUTPUT;
+}
+bool IsOutputMetalDirect(ShShaderOutput output)
+{
+ return output == SH_MSL_METAL_OUTPUT;
+}
+
+bool IsInShaderStorageBlock(TIntermTyped *node)
+{
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ return IsInShaderStorageBlock(swizzleNode->getOperand());
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirectInterfaceBlock:
+ case EOpIndexIndirect:
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ return IsInShaderStorageBlock(binaryNode->getLeft());
+ default:
+ return false;
+ }
+ }
+
+ const TType &type = node->getType();
+ return type.getQualifier() == EvqBuffer;
+}
+
+GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq)
+{
+ switch (iifq)
+ {
+ case EiifRGBA32F:
+ return GL_RGBA32F;
+ case EiifRGBA16F:
+ return GL_RGBA16F;
+ case EiifR32F:
+ return GL_R32F;
+ case EiifRGBA32UI:
+ return GL_RGBA32UI;
+ case EiifRGBA16UI:
+ return GL_RGBA16UI;
+ case EiifRGBA8UI:
+ return GL_RGBA8UI;
+ case EiifR32UI:
+ return GL_R32UI;
+ case EiifRGBA32I:
+ return GL_RGBA32I;
+ case EiifRGBA16I:
+ return GL_RGBA16I;
+ case EiifRGBA8I:
+ return GL_RGBA8I;
+ case EiifR32I:
+ return GL_R32I;
+ case EiifRGBA8:
+ return GL_RGBA8;
+ case EiifRGBA8_SNORM:
+ return GL_RGBA8_SNORM;
+ default:
+ return GL_NONE;
+ }
+}
+
+bool IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec, int shaderVersion)
+{
+ return (shaderVersion == 100 && !sh::IsWebGLBasedSpec(shaderSpec));
+}
+
+ImplicitTypeConversion GetConversion(TBasicType t1, TBasicType t2)
+{
+ if (t1 == t2)
+ return ImplicitTypeConversion::Same;
+
+ switch (t1)
+ {
+ case EbtInt:
+ switch (t2)
+ {
+ case EbtInt:
+ UNREACHABLE();
+ break;
+ case EbtUInt:
+ return ImplicitTypeConversion::Invalid;
+ case EbtFloat:
+ return ImplicitTypeConversion::Left;
+ default:
+ return ImplicitTypeConversion::Invalid;
+ }
+ break;
+ case EbtUInt:
+ switch (t2)
+ {
+ case EbtInt:
+ return ImplicitTypeConversion::Invalid;
+ case EbtUInt:
+ UNREACHABLE();
+ break;
+ case EbtFloat:
+ return ImplicitTypeConversion::Left;
+ default:
+ return ImplicitTypeConversion::Invalid;
+ }
+ break;
+ case EbtFloat:
+ switch (t2)
+ {
+ case EbtInt:
+ case EbtUInt:
+ return ImplicitTypeConversion::Right;
+ case EbtFloat:
+ UNREACHABLE();
+ break;
+ default:
+ return ImplicitTypeConversion::Invalid;
+ }
+ break;
+ default:
+ return ImplicitTypeConversion::Invalid;
+ }
+ return ImplicitTypeConversion::Invalid;
+}
+
+bool IsValidImplicitConversion(sh::ImplicitTypeConversion conversion, TOperator op)
+{
+ switch (conversion)
+ {
+ case sh::ImplicitTypeConversion::Same:
+ return true;
+ case sh::ImplicitTypeConversion::Left:
+ switch (op)
+ {
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ case EOpAdd:
+ case EOpSub:
+ case EOpMul:
+ case EOpDiv:
+ return true;
+ default:
+ break;
+ }
+ break;
+ case sh::ImplicitTypeConversion::Right:
+ switch (op)
+ {
+ case EOpAssign:
+ case EOpInitialize:
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ case EOpAdd:
+ case EOpSub:
+ case EOpMul:
+ case EOpDiv:
+ case EOpAddAssign:
+ case EOpSubAssign:
+ case EOpMulAssign:
+ case EOpDivAssign:
+ return true;
+ default:
+ break;
+ }
+ break;
+ case sh::ImplicitTypeConversion::Invalid:
+ break;
+ }
+ return false;
+}
+
+bool IsPrecisionApplicableToType(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtInt:
+ case EbtUInt:
+ case EbtFloat:
+ // TODO: find all types where precision is applicable; for example samplers.
+ // http://anglebug.com/6132
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsRedeclarableBuiltIn(const ImmutableString &name)
+{
+ return name == "gl_ClipDistance" || name == "gl_CullDistance" || name == "gl_LastFragData" ||
+ name == "gl_PerVertex" || name == "gl_Position" || name == "gl_PointSize";
+}
+
+size_t FindFieldIndex(const TFieldList &fieldList, const char *fieldName)
+{
+ for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
+ {
+ if (strcmp(fieldList[fieldIndex]->name().data(), fieldName) == 0)
+ {
+ return fieldIndex;
+ }
+ }
+ UNREACHABLE();
+ return 0;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/util.h b/gfx/angle/checkout/src/compiler/translator/util.h
new file mode 100644
index 0000000000..7d7a929f8a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/util.h
@@ -0,0 +1,108 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_UTIL_H_
+#define COMPILER_TRANSLATOR_UTIL_H_
+
+#include <stack>
+
+#include <GLSLANG/ShaderLang.h>
+#include "angle_gl.h"
+
+#include "compiler/translator/HashNames.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/Operator_autogen.h"
+#include "compiler/translator/Types.h"
+
+// If overflow happens, clamp the value to UINT_MIN or UINT_MAX.
+// Return false if overflow happens.
+bool atoi_clamp(const char *str, unsigned int *value);
+
+namespace sh
+{
+
+// Keeps track of whether an implicit conversion from int/uint to float is possible.
+// These conversions are supported in desktop GLSL shaders only.
+// Also keeps track of which side of operation should be converted.
+enum class ImplicitTypeConversion
+{
+ Same,
+ Left,
+ Right,
+ Invalid,
+};
+
+class TIntermBlock;
+class TSymbolTable;
+class TIntermTyped;
+
+float NumericLexFloat32OutOfRangeToInfinity(const std::string &str);
+
+// strtof_clamp is like strtof but
+// 1. it forces C locale, i.e. forcing '.' as decimal point.
+// 2. it sets the value to infinity if overflow happens.
+// 3. str should be guaranteed to be in the valid format for a floating point number as defined
+// by the grammar in the ESSL 3.00.6 spec section 4.1.4.
+// Return false if overflow happens.
+bool strtof_clamp(const std::string &str, float *value);
+
+GLenum GLVariableType(const TType &type);
+GLenum GLVariablePrecision(const TType &type);
+bool IsVaryingIn(TQualifier qualifier);
+bool IsVaryingOut(TQualifier qualifier);
+bool IsVarying(TQualifier qualifier);
+bool IsMatrixGLType(GLenum type);
+bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier);
+bool IsTessellationControlShaderInput(GLenum shaderType, TQualifier qualifier);
+bool IsTessellationControlShaderOutput(GLenum shaderType, TQualifier qualifier);
+bool IsTessellationEvaluationShaderInput(GLenum shaderType, TQualifier qualifier);
+InterpolationType GetInterpolationType(TQualifier qualifier);
+InterpolationType GetFieldInterpolationType(TQualifier qualifier);
+
+// Returns array brackets including size with outermost array size first, as specified in GLSL ES
+// 3.10 section 4.1.9.
+ImmutableString ArrayString(const TType &type);
+
+ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap);
+
+TType GetShaderVariableBasicType(const sh::ShaderVariable &var);
+
+void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable);
+
+bool IsBuiltinOutputVariable(TQualifier qualifier);
+bool IsBuiltinFragmentInputVariable(TQualifier qualifier);
+bool CanBeInvariantESSL1(TQualifier qualifier);
+bool CanBeInvariantESSL3OrGreater(TQualifier qualifier);
+bool IsShaderOutput(TQualifier qualifier);
+bool IsFragmentOutput(TQualifier qualifier);
+bool IsOutputESSL(ShShaderOutput output);
+bool IsOutputGLSL(ShShaderOutput output);
+bool IsOutputHLSL(ShShaderOutput output);
+bool IsOutputVulkan(ShShaderOutput output);
+bool IsOutputMetal(ShShaderOutput output);
+bool IsOutputMetalDirect(ShShaderOutput output);
+
+bool IsInShaderStorageBlock(TIntermTyped *node);
+
+GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq);
+// ESSL 1.00 shaders nest function body scope within function parameter scope
+bool IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec, int shaderVersion);
+
+// Helper functions for implicit conversions
+ImplicitTypeConversion GetConversion(TBasicType t1, TBasicType t2);
+
+bool IsValidImplicitConversion(ImplicitTypeConversion conversion, TOperator op);
+
+// Whether the given basic type requires precision.
+bool IsPrecisionApplicableToType(TBasicType type);
+
+// Whether this is the name of a built-in that can be redeclared by the shader.
+bool IsRedeclarableBuiltIn(const ImmutableString &name);
+
+size_t FindFieldIndex(const TFieldList &fieldList, const char *fieldName);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_UTIL_H_